#34634: Creating objects with nested MTI crashes.
-------------------------------------+-------------------------------------
     Reporter:  Mariusz Felisiak     |                    Owner:  Akash
                                     |  Kumar Sen
         Type:  Bug                  |                   Status:  assigned
    Component:  Database layer       |                  Version:  4.2
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:                       |             Triage Stage:  Accepted
    Has patch:  1                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  1
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by Akash Kumar Sen):

 Possible MTI Scenarios with two bases in Django

 **Example Model:**
 {{{
 class CommonChild(FirstParent, SecondParent):
     pass
 }}}

 **Case 1 -- FirstParent and Secondparent are does not have a common
 ancestor**
 - This scenario shows no regression

 **Case 2 -- FirstParent and Secondparent have a common ancestor**
 - This scenario shows regression only with primary key with default, as
 mentioned in #33414

 **Case 3 -- FirstParent is the ancestor of SecondParent**
 - This shows the following {{{TypeError}}}. (I think this is the expected
 scenario)

 {{{
 TypeError: Cannot create a consistent method resolution
 order (MRO) for bases FirstParent, Secondparent
 }}}

 **Case 4 -- Secondparent is the ancestor of FirstParent(Case mentioned
 here)**
 - I tried to print {{{ItalianRestaurantManyParents._meta.get_fields()}}} ,
 it contained all the fields of the {{{Place}}} model twice, that means we
 are having conflicts passing all the checks here.
 - As the fields in {{{ItalianRestaurantManyParents}}} is already a
 superset of all the fields of {{{Place}}} I don't think it makes any real
 world use case scenario for allowing such this kind of MTI scenario.
 - **Possible solution 1 :** would be to put a check and show a similar
 kind of error like case 3.
 - **Possible solution 2 :** would be to let the child eat the parent
 during initialization of the model, like the following. (This seems to be
 passing all the tests, just have one problem. When the user defines a
 custom {{{OneToOneField}}} pointer to the SecondParent)
 {{{
 class ModelBase(type):
     """Metaclass for all models."""

     def __new__(cls, name, bases, attrs, **kwargs):
         super_new = super().__new__

         # Also ensure initialization is only performed for subclasses of
 Model
         # (excluding Model class itself).
         parents = [b for b in bases if isinstance(b, ModelBase)]
         for parent in parents:
             if any(
                 issubclass(other_parent, parent)
                 for other_parent in parents
                 if not other_parent == parent
             ):
                 parents.remove(parent)
         if not parents:
             return super_new(cls, name, bases, attrs)
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/34634#comment:8>
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/01070188b4bfb264-4103e90a-f0c4-4564-b550-1d39448ca0a7-000000%40eu-central-1.amazonses.com.

Reply via email to