Ticket #8309: genericforeignkey_fail_in_abstract_models_r8507.diff
File genericforeignkey_fail_in_abstract_models_r8507.diff, 4.9 KB (added by , 16 years ago) |
---|
-
django/db/models/base.py
95 95 # Things without _meta aren't functional models, so they're 96 96 # uninteresting parents. 97 97 continue 98 field_names = set([f.name for f in new_class._meta.local_fields + \ 99 new_class._meta.virtual_fields + \ 100 new_class._meta.many_to_many ]) 98 101 if not base._meta.abstract: 99 102 if base in o2o_map: 100 103 field = o2o_map[base] … … 108 111 new_class._meta.parents[base] = field 109 112 else: 110 113 # The abstract base class case. 111 names = set([f.name for f in new_class._meta.local_fields + new_class._meta.many_to_many]) 112 for field in base._meta.local_fields + base._meta.local_many_to_many: 113 if field.name in names: 114 parent_fields = base._meta.local_fields + \ 115 base._meta.local_many_to_many 116 for field in parent_fields: 117 if field.name in field_names: 114 118 raise FieldError('Local field %r in class %r clashes with field of similar name from abstract base class %r' 115 119 % (field.name, name, base.__name__)) 116 120 new_class.add_to_class(field.name, copy.deepcopy(field)) 117 121 # checking for virtual fields, like GenericForeignKey (see #8309) 122 for field in base._meta.virtual_fields: 123 if base._meta.abstract and field.name in field_names: 124 raise FieldError('Local field %r in class %r clashes with field of similar name from abstract base class %r' 125 % (field.name, name, base.__name__)) 126 new_class.add_to_class(field.name, copy.deepcopy(field)) 118 127 if abstract: 119 128 # Abstract base models can't be instantiated and don't appear in 120 129 # the list of models for an app. We do the final setup for them a -
django/db/models/options.py
26 26 class Options(object): 27 27 def __init__(self, meta, app_label=None): 28 28 self.local_fields, self.local_many_to_many = [], [] 29 self.virtual_fields = [] 29 30 self.module_name, self.verbose_name = None, None 30 31 self.verbose_name_plural = None 31 32 self.db_table = '' … … 152 153 if hasattr(self, '_name_map'): 153 154 del self._name_map 154 155 156 def add_virtual_field(self, field): 157 self.virtual_fields.append(field) 158 155 159 def setup_pk(self, field): 156 160 if not self.pk and field.primary_key: 157 161 self.pk = field -
django/contrib/contenttypes/generic.py
28 28 def contribute_to_class(self, cls, name): 29 29 # Make sure the fields exist (these raise FieldDoesNotExist, 30 30 # which is a fine error to raise here) 31 cls._meta.add_virtual_field(self) 31 32 self.name = name 33 self.attname = name 32 34 self.model = cls 33 35 self.cache_attr = "_%s_cache" % name 34 36 -
tests/modeltests/generic_relations/models.py
75 75 def __unicode__(self): 76 76 return self.name 77 77 78 class ValuableTaggedItem(TaggedItem): 79 value = models.PositiveSmallIntegerField() 80 81 78 82 __test__ = {'API_TESTS':""" 79 83 # Create the world in 7 lines of code... 80 84 >>> lion = Animal(common_name="Lion", latin_name="Panthera leo") … … 211 215 <p><label for="id_generic_relations-taggeditem-content_type-object_id-1-tag">Tag:</label> <input id="id_generic_relations-taggeditem-content_type-object_id-1-tag" type="text" name="generic_relations-taggeditem-content_type-object_id-1-tag" maxlength="50" /></p> 212 216 <p><label for="id_generic_relations-taggeditem-content_type-object_id-1-DELETE">Delete:</label> <input type="checkbox" name="generic_relations-taggeditem-content_type-object_id-1-DELETE" id="id_generic_relations-taggeditem-content_type-object_id-1-DELETE" /><input type="hidden" name="generic_relations-taggeditem-content_type-object_id-1-id" id="id_generic_relations-taggeditem-content_type-object_id-1-id" /></p> 213 217 218 # GenericForeignKey should work with abstract classes (see #8309) ############# 219 220 >>> valuedtag = ValuableTaggedItem(content_object=quartz, tag="shiny", value=10) 221 214 222 """}