Ticket #10808: 10808.diff

File 10808.diff, 2.5 KB (added by SmileyChris, 6 years ago)

Single patch with tests & changes

  • django/db/models/base.py

     
    273273        # Now we're left with the unprocessed fields that *must* come from
    274274        # keywords, or default.
    275275
     276        # In the case of diamond inheritance, where B and C inherit from A, and
     277        # D inherits from B and C, D will have "redundant" copies of each of
     278        # A's fields. As we iterate through all the fields, the second time we
     279        # see a field we run the risk of reassigning it the default value, so
     280        # if a field has already been seen in assigned_fields, we ignore it.
     281        assigned_fields = set()
    276282        for field in fields_iter:
     283            if field.attname in assigned_fields:
     284                continue
    277285            is_related_object = False
    278286            # This slightly odd construct is so that we can access any
    279287            # data-descriptor object (DeferredAttribute) without triggering its
     
    311319                setattr(self, field.name, rel_obj)
    312320            else:
    313321                setattr(self, field.attname, val)
     322            assigned_fields.add(field.attname)
    314323
    315324        if kwargs:
    316325            for prop in kwargs.keys():
  • tests/modeltests/model_inheritance/models.py

     
    116116    def __unicode__(self):
    117117        return u"%s the parking lot" % self.name
    118118
     119#
     120# Diamond inheritance test
     121#
     122class FoodPlace(models.Model):
     123    name = models.CharField(max_length=255)
     124
     125class Bar(FoodPlace):
     126    pass
     127
     128class Pizzeria(FoodPlace):
     129    pass
     130
     131class PizzeriaBar(Bar, Pizzeria):
     132    pizza_bar_specific_field = models.CharField(max_length=255)
     133
    119134__test__ = {'API_TESTS':"""
    120135# The Student and Worker models both have 'name' and 'age' fields on them and
    121136# inherit the __unicode__() method, just as with normal Python subclassing.
     
    3103253
    311326>>> settings.DEBUG = False
    312327
     328# Test of diamond inheritance __init__. If B and C inherit from A, and D inherits from B and C, we should be able to use __init__ for D to properly set all the fields, regardless of the redundant copies of A's fields that D inherits from B and C.
     329
     330>>> p = PizzeriaBar(name="Mike's", pizza_bar_specific_field="Doodle")
     331>>> p.name == "Mike's"
     332True
     333>>> p.pizza_bar_specific_field == "Doodle"
     334True
    313335"""}
Back to Top