Changeset 8855
- Timestamp:
- 09/02/08 10:26:00 (3 months ago)
- Files:
-
- django/trunk/django/contrib/contenttypes/generic.py (modified) (1 diff)
- django/trunk/django/db/models/base.py (modified) (3 diffs)
- django/trunk/django/db/models/options.py (modified) (2 diffs)
- django/trunk/tests/modeltests/generic_relations/models.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/trunk/django/contrib/contenttypes/generic.py
r8644 r8855 25 25 26 26 def contribute_to_class(self, cls, name): 27 # Make sure the fields exist (these raise FieldDoesNotExist,28 # which is a fine error to raise here)29 27 self.name = name 30 28 self.model = cls 31 29 self.cache_attr = "_%s_cache" % name 30 cls._meta.add_virtual_field(self) 32 31 33 32 # For some reason I don't totally understand, using weakrefs here doesn't work. django/trunk/django/db/models/base.py
r8851 r8855 88 88 # uninteresting parents. 89 89 continue 90 91 # All the fields of any type declared on this model 92 new_fields = new_class._meta.local_fields + \ 93 new_class._meta.many_to_many + \ 94 new_class._meta.virtual_fields 95 field_names = set([f.name for f in new_fields]) 96 97 # Concrete classes... 90 98 if not base._meta.abstract: 91 99 if base in o2o_map: … … 99 107 new_class.add_to_class(attr_name, field) 100 108 new_class._meta.parents[base] = field 101 else: 102 # The abstract base class case. 103 names = set([f.name for f in new_class._meta.local_fields + new_class._meta.many_to_many]) 104 for field in base._meta.local_fields + base._meta.local_many_to_many: 105 if field.name in names: 106 raise FieldError('Local field %r in class %r clashes with field of similar name from abstract base class %r' 107 % (field.name, name, base.__name__)) 109 110 # .. and abstract ones. 111 else: 112 # Check for clashes between locally declared fields and those on the ABC. 113 parent_fields = base._meta.local_fields + base._meta.local_many_to_many 114 for field in parent_fields: 115 if field.name in field_names: 116 raise FieldError('Local field %r in class %r clashes '\ 117 'with field of similar name from '\ 118 'abstract base class %r' % \ 119 (field.name, name, base.__name__)) 108 120 new_class.add_to_class(field.name, copy.deepcopy(field)) 109 121 … … 116 128 new_manager = manager._copy_to_model(new_class) 117 129 new_class.add_to_class(mgr_name, new_manager) 130 131 # Inherit virtual fields (like GenericForeignKey) from the parent class 132 for field in base._meta.virtual_fields: 133 if base._meta.abstract and field.name in field_names: 134 raise FieldError('Local field %r in class %r clashes '\ 135 'with field of similar name from '\ 136 'abstract base class %r' % \ 137 (field.name, name, base.__name__)) 138 new_class.add_to_class(field.name, copy.deepcopy(field)) 139 118 140 if abstract: 119 141 # Abstract base models can't be instantiated and don't appear in django/trunk/django/db/models/options.py
r8851 r8855 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 … … 156 157 del self._name_map 157 158 159 def add_virtual_field(self, field): 160 self.virtual_fields.append(field) 161 158 162 def setup_pk(self, field): 159 163 if not self.pk and field.primary_key: django/trunk/tests/modeltests/generic_relations/models.py
r8815 r8855 27 27 def __unicode__(self): 28 28 return self.tag 29 30 class ValuableTaggedItem(TaggedItem): 31 value = models.PositiveIntegerField() 29 32 30 33 class Comparison(models.Model): … … 205 208 [<Comparison: tiger is stronger than None>] 206 209 210 # GenericForeignKey should work with subclasses (see #8309) 211 >>> quartz = Mineral.objects.create(name="Quartz", hardness=7) 212 >>> valuedtag = ValuableTaggedItem(content_object=quartz, tag="shiny", value=10) 213 >>> valuedtag.save() 214 >>> valuedtag.content_object 215 <Mineral: Quartz> 207 216 208 217 # GenericInlineFormSet tests ##################################################
