Ticket #14705: ticket14705.diff
File ticket14705.diff, 5.2 KB (added by , 14 years ago) |
---|
-
django/db/models/base.py
100 100 new_class._meta.virtual_fields 101 101 field_names = set([f.name for f in new_fields]) 102 102 103 # Things without _meta aren't functional models, so they're 104 # uninteresting parents. 105 parents = [cls for cls in parents if hasattr(cls, '_meta')] 106 new_class._meta.bases = parents 107 103 108 # Basic setup for proxy models. 104 109 if is_proxy: 105 110 base = None 106 for parent in [cls for cls in parents if hasattr(cls, '_meta')]:111 for parent in parents: 107 112 if parent._meta.abstract: 108 113 if parent._meta.fields: 109 114 raise TypeError("Abstract base class containing model fields not permitted for proxy model '%s'." % name) … … 128 133 129 134 for base in parents: 130 135 original_base = base 131 if not hasattr(base, '_meta'):132 # Things without _meta aren't functional models, so they're133 # uninteresting parents.134 continue135 136 136 parent_fields = base._meta.local_fields + base._meta.local_many_to_many 137 137 # Check for clashes between locally declared fields and those 138 138 # on the base classes (we cannot handle shadowed fields at the -
django/db/models/options.py
47 47 self.proxy = False 48 48 self.proxy_for_model = None 49 49 self.parents = SortedDict() 50 self.bases = [] 50 51 self.duplicate_targets = {} 51 52 self.auto_created = False 52 53 … … 228 229 229 230 def _fill_fields_cache(self): 230 231 cache = [] 231 for parent in self.parents: 232 for field, model in parent._meta.get_fields_with_model(): 233 if model: 232 local_fields = list(self.local_fields) 233 for field in self.local_fields: 234 if isinstance(field, AutoField): 235 cache.append((field, None)) 236 local_fields.remove(field) 237 break 238 for base in self.bases: 239 for field, model in base._meta.get_fields_with_model(): 240 if not model: 241 model = base 242 if model._meta.abstract: 243 field_index = local_fields.index(field) 244 cache.append((local_fields[field_index], None)) 245 del local_fields[field_index] 246 else: 234 247 cache.append((field, model)) 235 else: 236 cache.append((field, parent)) 237 cache.extend([(f, None) for f in self.local_fields]) 248 if base in self.parents: 249 field = self.parents[base] 250 if field: 251 cache.append((field, None)) 252 local_fields.remove(field) 253 cache.extend([(f, None) for f in local_fields]) 238 254 self._field_cache = tuple(cache) 239 255 self._field_name_cache = [x for x, _ in cache] 240 256 -
tests/modeltests/model_inheritance/tests.py
4 4 from django.test import TestCase 5 5 6 6 from models import (Chef, CommonInfo, ItalianRestaurant, ParkingLot, Place, 7 Post, Restaurant, Student, StudentWorker, Supplier, Worker )7 Post, Restaurant, Student, StudentWorker, Supplier, Worker, OneTwo, TwoOne) 8 8 9 9 10 10 class ModelInheritanceTests(TestCase): … … 269 269 self.assertNumQueries(1, 270 270 lambda: ItalianRestaurant.objects.select_related("chef")[0].chef 271 271 ) 272 273 names = [field.name for field in OneTwo._meta.fields] 274 self.assertEqual(["id", "field_one", "field_two", "field_three", 275 "field_four"], names) 276 277 names = [field.name for field in TwoOne._meta.fields] 278 self.assertEqual(["id", "field_three", "field_four", "field_one", 279 "field_two"], names) 280 -
tests/modeltests/model_inheritance/models.py
119 119 def __unicode__(self): 120 120 return u"%s the parking lot" % self.name 121 121 122 class AbstractModelOne(models.Model): 123 field_one = models.BooleanField() 124 field_two = models.TextField() 125 126 class Meta: 127 abstract = True 128 129 class AbstractModelTwo(models.Model): 130 field_three = models.BooleanField() 131 field_four = models.TextField() 132 133 class Meta: 134 abstract = True 135 136 class OneTwo(AbstractModelOne, AbstractModelTwo): 137 pass 138 139 class TwoOne(AbstractModelTwo, AbstractModelOne): 140 pass 141 122 142 # 123 143 # Abstract base classes with related models where the sub-class has the 124 144 # same name in a different app and inherits from the same abstract base