Code

Changes between Version 12 and Version 13 of ModelInheritance


Ignore:
Timestamp:
02/27/06 14:26:06 (8 years ago)
Author:
cell@…
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • ModelInheritance

    v12 v13  
    150150== Ramblings on Magic Removal Subclassing == 
    151151 
    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: 
     152Consider the following variation on the above restaurant example: 
    165153 
    166154{{{ 
     
    172160}}} 
    173161 
    174 to something more like this: 
     162If 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().  
     163Thus, by the time the Restaurant class is created, the Place class which it inherits from actually looks more like this: 
    175164 
    176165{{{ 
     
    181170    _meta = ... 
    182171}}} 
     172 
     173Thus, there is simply no 'name' field for it to inherit.