#34555: ModelBase metaclass implementation prevents addition of model fields via
__init_subclass__
-------------------------------------+-------------------------------------
     Reporter:  hottwaj              |                    Owner:  nobody
         Type:  Bug                  |                   Status:  closed
    Component:  Database layer       |                  Version:  4.2
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:  wontfix
     Keywords:  ModelBase            |             Triage Stage:
  init_subclass                      |  Unreviewed
    Has patch:  1                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Comment (by Clifford Gama):

 Replying to [comment:10 Carlton Gibson]:
 > Related too is #27880 ''Use `__set_name__` to replace some usages of
 contribute_to_class'', I think

 Indeed, if #27880 gets added then this might be fixed, thanks to
 `Options.__set_name__()`, `_meta` will be added when the class is first
 created.

 I say *might* because as the PR for #27880 currently stands,
 `Field.contribute_to_class()` will still be called after the class is
 first created, because `Field.contribute_to_class()` is semi-private API
 and has to be deprecated rather than replaced.

 Regardless of whether `Field.contribute_to_class()` is deprecated for
 `Field.__set_name__()`, if
 
[https://github.com/django/django/pull/18621/commits/f5fa7b4986e0ef2c994dffc95c003f55bf7dbe8c
 f5fa7b4] is added allowing Options to be added on class creation (i.e.
 `type.__new__()` in `ModelBase`) then the following would work

 {{{#!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)
         # This will work because `_meta` is available when init-subclass
 is called
         author.contribute_to_class(cls, 'author')
         # author.__set_name__(cls, 'author')  if #27880 is landed for
 Fields

 class Author(Model):
     name = CharField(max_len = 256, unique = True)

 class Book(BaseBookModel, author_model_cls = Author):
     pass
 }}}
-- 
Ticket URL: <https://code.djangoproject.com/ticket/34555#comment:12>
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/010701927ae823ae-e764c2b4-849b-4ad0-b4cd-6ecb3f3ae687-000000%40eu-central-1.amazonses.com.

Reply via email to