Ticket #10808: 10808b.diff
File 10808b.diff, 5.1 KB (added by , 15 years ago) |
---|
-
django/db/models/base.py
273 273 # Now we're left with the unprocessed fields that *must* come from 274 274 # keywords, or default. 275 275 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() 276 282 for field in fields_iter: 283 if field.attname in assigned_fields: 284 continue 277 285 is_related_object = False 278 286 # This slightly odd construct is so that we can access any 279 287 # data-descriptor object (DeferredAttribute) without triggering its … … 311 319 setattr(self, field.name, rel_obj) 312 320 else: 313 321 setattr(self, field.attname, val) 322 assigned_fields.add(field.attname) 314 323 315 324 if kwargs: 316 325 for prop in kwargs.keys(): -
django/forms/models.py
793 793 from django.db.models import ForeignKey 794 794 opts = model._meta 795 795 if fk_name: 796 fks_to_parent = [f for f in opts.fields if f.name == fk_name] 797 if len(fks_to_parent) == 1: 798 fk = fks_to_parent[0] 799 if not isinstance(fk, ForeignKey) or \ 800 (fk.rel.to != parent_model and 801 fk.rel.to not in parent_model._meta.get_parent_list()): 802 raise Exception("fk_name '%s' is not a ForeignKey to %s" % (fk_name, parent_model)) 803 elif len(fks_to_parent) == 0: 804 raise Exception("%s has no field named '%s'" % (model, fk_name)) 796 fk = opts.get_field(fk_name,many_to_many=False) 797 if not isinstance(fk, ForeignKey) or \ 798 (fk.rel.to != parent_model and 799 fk.rel.to not in parent_model._meta.get_parent_list()): 800 raise Exception("fk_name '%s' is not a ForeignKey to %s" % (fk_name, parent_model)) 805 801 else: 806 802 # Try to discover what the ForeignKey from model to parent_model is 807 803 fks_to_parent = [ -
tests/modeltests/model_inheritance/models.py
116 116 def __unicode__(self): 117 117 return u"%s the parking lot" % self.name 118 118 119 # 120 # Diamond inheritance test 121 # 122 123 class Owner(models.Model): 124 name = models.CharField(max_length=255) 125 126 class FoodPlace(models.Model): 127 name = models.CharField(max_length=255) 128 owner = models.ForeignKey(Owner,blank=True,null=True) 129 130 class Bar(FoodPlace): 131 pass 132 133 class Pizzeria(FoodPlace): 134 pass 135 136 class PizzeriaBar(Bar, Pizzeria): 137 pizza_bar_specific_field = models.CharField(max_length=255) 138 119 139 __test__ = {'API_TESTS':""" 120 140 # The Student and Worker models both have 'name' and 'age' fields on them and 121 141 # inherit the __unicode__() method, just as with normal Python subclassing. … … 310 330 3 311 331 >>> settings.DEBUG = False 312 332 333 # 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. 334 335 >>> p = PizzeriaBar(name="Mike's", pizza_bar_specific_field="Doodle") 336 >>> p.name == "Mike's" 337 True 338 >>> p.pizza_bar_specific_field == "Doodle" 339 True 340 341 #Note that patch 10808.diff fixes only one symptom, not the real problem. 342 #The real problem is that in case of diamond inheritance there are duplicate field definitions: 343 344 >>> print ' '.join([f.name for f in p._meta.fields]) 345 id name owner foodplace_ptr id name owner foodplace_ptr pizzeria_ptr bar_ptr pizza_bar_specific_field 346 347 #The first 4 fields occur twice. 348 #My patch won't fix the real problem, but another symptom. 349 #When the top-level model of your diamond structure contains a ForeignKey, then you get problems when trying to create inline formsets: 350 351 >>> from django.forms.models import inlineformset_factory 352 >>> f = inlineformset_factory(Owner,PizzeriaBar) 353 Traceback (most recent call last): 354 ... 355 Exception: <class '...PizzeriaBar'> has more than 1 ForeignKey to <class '....Owner'> 356 357 #The workaround I suggest for this problem is to specify the fk_name explicitly: 358 359 >>> from django.forms.models import inlineformset_factory 360 >>> f = inlineformset_factory(Owner,PizzeriaBar,fk_name='owner') 361 362 #Unfortunately this workaround needs another patch 10808b.diff because inlineformset_factory() just can't imagine that a model can have two fields with the same name. 363 364 365 313 366 """}