Changes between Version 12 and Version 13 of ModelInheritance
- Timestamp:
- Feb 27, 2006, 4:26:06 PM (19 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
ModelInheritance
v12 v13 150 150 == Ramblings on Magic Removal Subclassing == 151 151 152 For the above Restaurant example: 153 154 {{{ 155 class Place(models.Model): 156 name = models.CharField(maxlength=50) 157 158 class Restaurant(Place): 159 description = models.TextField() 160 }}} 161 162 we want Restaurant to have a 'name' CharField. Looking at our above example, it would seem that 'name' should automatically be inherited by Restaurant. However, this is not the case, as Django is using metaclasses to modify the default class creation behavior. 'Place' is not created strictly as defined above. The ModelBase metaclass instead creates a new class from scratch (see dm/models/base.py), and each of the field attributes are added to the class in such as way that they are not inherited by subclasses. Note how 'name' would not show up under a call to dir(Place). 163 164 Each of the fields is added to the class via a call to add_to_class(). This in turn calls contribute_to_class in the case of field objects, rather than calling setattr(), which is why the fields of a parent class are not available to the child class for inheriting. In other words, by the time Restaurant is created, the definition of it's parent would change from this: 152 Consider the following variation on the above restaurant example: 165 153 166 154 {{{ … … 172 160 }}} 173 161 174 to something more like this: 162 If Restaurant were to inherit from this, it would not automatically have a 'name' CharField. This is because Django uses a metaclass to modify the default class creation behavior. The ModelBase metaclass creates a new class from scratch, and then selectively pulls items from the Place class as defined above and adds them to this new class, which allows it to handle Field objects specially. For each of the class's attributes, add_to_class() is called. If add_to_class finds a 'contribute_to_class' attribute, ModelBase knows it is dealing with a Field object, and calls contribute_to_class. Otherwise, it just adds it to the new class via setattr(). 163 Thus, by the time the Restaurant class is created, the Place class which it inherits from actually looks more like this: 175 164 176 165 {{{ … … 181 170 _meta = ... 182 171 }}} 172 173 Thus, there is simply no 'name' field for it to inherit.