#34555: Dynamic model fields without using a metaclass
-------------------------------------+-------------------------------------
Reporter: hottwaj | Owner: nobody
Type: New | Status: new
feature |
Component: Database | Version: 4.2
layer (models, ORM) | Keywords: ModelBase
Severity: Normal | init_subclass
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
I'd like to be able to write some abstract model "templates" that can be
re-used/customised in various other django apps. Some of these templates
require ForeignKeys to other "templates" which are also abstract.
Obviously ForeignKeys to Abstract models are not possible
Having used metaclasses in a similar situation before, but hoping to find
a less complex approach, I thought I might be able to implement this by
providing a __init_subclass__ method on my "template" model, with that
method designed to set up the ForeignKey to a given concrete model, but
this does not work. It seems that __init_subclass__ is called after
ModelBase.__new__ collects fields that require "contribute_to_class", so
the fields I add in __init_subclass__ are never "seen" by e.g. the
migration builder.
Example approach below (but note this does not work for reasons explained
above):
{{{#!python
from django.db.models import Model, ForeignKey, CASCADE, CharField
class BaseBookModel(Model):
class Meta:
abstract = True
def __init_subclass__(cls, author_model_cls: Type[Model], **kwargs,):
super().__init_subclass__(**kwargs)
author = ForeignKey(author_model_cls, on_delete = CASCADE)
cls.add_to_class('author', author)
class Author(Model):
name = CharField(max_len = 256, unique = True)
class Book(BaseBookModel, author_model_cls = Author):
pass
}}}
Essentially what I'd like is some way of doing some extra work after
BaseModel.__new__ is called without resorting to having to write a
metaclass for BaseBookModel - I'm just adding some extra fields and a
metaclass is complex for most mortals to read let alone write. There does
not seem to be an appropriate hook method that I can override to do this
for every subclass of BaseBookModel
Thanks for reading and appreciate any thoughts!
--
Ticket URL: <https://code.djangoproject.com/ticket/34555>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/010701880664eb04-afaaa5e4-3c3c-465d-a6f5-558ea4376edb-000000%40eu-central-1.amazonses.com.