| | 2076 | Model inheritance |
|---|
| | 2077 | ================= |
|---|
| | 2078 | |
|---|
| | 2079 | **New in Django development version** |
|---|
| | 2080 | |
|---|
| | 2081 | Model inheritance in Django works almost identically to the way normal class |
|---|
| | 2082 | inheritance works in Python. The only decision you have to make is whether you |
|---|
| | 2083 | want the parent models to be models in their own right (with their own |
|---|
| | 2084 | database tables), or if the parents are just holders of common information |
|---|
| | 2085 | that will only be visible through the child models. |
|---|
| | 2086 | |
|---|
| | 2087 | Often, you will just want to use the parent class to hold information that you |
|---|
| | 2088 | don't want to have to type out for each child model. This class isn't going to |
|---|
| | 2089 | ever be used in isolation, so `abstract base classes`_ are what you're after. However, if you're subclassing an existing model (perhaps something from another application entirely), or want each model to have its own database table, `multi-table inheritance`_ is the way to go. |
|---|
| | 2090 | |
|---|
| | 2091 | Abstract base classes |
|---|
| | 2092 | --------------------- |
|---|
| | 2093 | |
|---|
| | 2094 | Abstract base classes are useful when you want to put some common information |
|---|
| | 2095 | into a number of other models. You write your base class and put |
|---|
| | 2096 | ``abstract=True`` in the ``Meta`` class. This model will then not be used to |
|---|
| | 2097 | create any database table. Instead, when it is used as a base class for other |
|---|
| | 2098 | models, its fields will be added to those of the child class. It is an error |
|---|
| | 2099 | to have fields in the abstract base class with the same name as those in the |
|---|
| | 2100 | child (and Django will raise an exception). |
|---|
| | 2101 | |
|---|
| | 2102 | An example:: |
|---|
| | 2103 | |
|---|
| | 2104 | class CommonInfo(models.Model): |
|---|
| | 2105 | name = models.CharField(max_length=100) |
|---|
| | 2106 | age = models.PositiveIntegerField() |
|---|
| | 2107 | |
|---|
| | 2108 | class Meta: |
|---|
| | 2109 | abstract = True |
|---|
| | 2110 | |
|---|
| | 2111 | class Student(CommonInfo): |
|---|
| | 2112 | home_group = models.CharField(max_length=5) |
|---|
| | 2113 | |
|---|
| | 2114 | The ``Student`` model will have three fields: ``name``, ``age`` and |
|---|
| | 2115 | ``home_group``. The ``CommonInfo`` model cannot be used as a normal Django |
|---|
| | 2116 | model, since it is an abstract base class. It does not generate a database |
|---|
| | 2117 | table or have a manager or anything like that. |
|---|
| | 2118 | |
|---|
| | 2119 | For many uses, this type of model inheritance will be exactly what you want. |
|---|
| | 2120 | It provides a way to factor out common information at the Python level, whilst |
|---|
| | 2121 | still only creating one database table per child model at the database level. |
|---|
| | 2122 | |
|---|
| | 2123 | ``Meta`` inheritance |
|---|
| | 2124 | ~~~~~~~~~~~~~~~~~~~~ |
|---|
| | 2125 | |
|---|
| | 2126 | When an abstract base class is created, Django makes any ``Meta`` inner class |
|---|
| | 2127 | you declared on the base class available as an attribute. If a child class |
|---|
| | 2128 | does not declared its own ``Meta`` class, it will inherit the parent's |
|---|
| | 2129 | ``Meta``. If the child wants to extend the parent's ``Meta`` class, it can |
|---|
| | 2130 | subclass it. For example:: |
|---|
| | 2131 | |
|---|
| | 2132 | class CommonInfo(models.Model): |
|---|
| | 2133 | ... |
|---|
| | 2134 | class Meta: |
|---|
| | 2135 | abstract = True |
|---|
| | 2136 | ordering = ['name'] |
|---|
| | 2137 | |
|---|
| | 2138 | class Student(CommonInfo): |
|---|
| | 2139 | ... |
|---|
| | 2140 | class Meta(CommonInfo.Meta): |
|---|
| | 2141 | db_table = 'student_info' |
|---|
| | 2142 | |
|---|
| | 2143 | Django does make one adjustment to the ``Meta`` class of an abstract base |
|---|
| | 2144 | class: before installing the ``Meta`` attribute, it sets ``abstract=False``. |
|---|
| | 2145 | This means that children of abstract base classes don't automatically become |
|---|
| | 2146 | abstract classes themselves. Of course, you can make an abstract base class |
|---|
| | 2147 | that inherits from another abstract base class. You just need to remember to |
|---|
| | 2148 | explicitly set ``abstract=True`` each time. |
|---|
| | 2149 | |
|---|
| | 2150 | Some attributes won't make sense to include in the ``Meta`` class of an |
|---|
| | 2151 | abstract base class. For example, including ``db_table`` would mean that all |
|---|
| | 2152 | the child classes (the ones that don't specify their own ``Meta``) would use |
|---|
| | 2153 | the same database table, which is almost certainly not what you want. |
|---|
| | 2154 | |
|---|
| | 2155 | Be careful with ``related_name`` |
|---|
| | 2156 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| | 2157 | |
|---|
| | 2158 | If you are using the ``related_name`` attribute on a ``ForeignKey`` or |
|---|
| | 2159 | ``ManyToManyField``, you must always specify a *unique* reverse name for the |
|---|
| | 2160 | field. This would normally cause a problem in abstract base classes, since the |
|---|
| | 2161 | fields on this class are included into each of the child classes, with exactly |
|---|
| | 2162 | the same values for the attributes (including ``related_name``) each time. |
|---|
| | 2163 | |
|---|
| | 2164 | To work around this problem, when you are using ``related_name`` in an |
|---|
| | 2165 | abstract base class (only), part of the name should be the string |
|---|
| | 2166 | ``'%(class)s'``. This is replaced by the lower-cased name of the child class |
|---|
| | 2167 | that the field is used in. Since each class has a different name, each related |
|---|
| | 2168 | name will end up being different. For example:: |
|---|
| | 2169 | |
|---|
| | 2170 | class Base(models.Model): |
|---|
| | 2171 | m2m = models.ManyToMany(OtherModel, related_name="%(class)s_related") |
|---|
| | 2172 | |
|---|
| | 2173 | class Meta: |
|---|
| | 2174 | abstract = True |
|---|
| | 2175 | |
|---|
| | 2176 | class ChildA(Base): |
|---|
| | 2177 | pass |
|---|
| | 2178 | |
|---|
| | 2179 | class ChildB(Base): |
|---|
| | 2180 | pass |
|---|
| | 2181 | |
|---|
| | 2182 | The reverse name of the ``ChildA.m2m`` field will be ``childa_related``, |
|---|
| | 2183 | whilst the reverse name of the ``ChildB.m2m`` field will be |
|---|
| | 2184 | ``childb_related``. It is up to you how you use the ``'%(class)s'`` portion to |
|---|
| | 2185 | construct your related name, but if you forget to use it, Django will raise |
|---|
| | 2186 | errors when you validate your models (or run ``syncdb``). |
|---|
| | 2187 | |
|---|
| | 2188 | If you don't specify a ``related_name`` attribute for a field in an abstract |
|---|
| | 2189 | base class, the default reverse name will be the name of the child class |
|---|
| | 2190 | followed by ``'_set'``, just as it normally would be if you'd declared the field directly on the child class. For example, in the above code, if the ``related_name`` attribute was omitted, the reverse name for the ``m2m`` field would be ``childa_set`` in the ``ChildA`` case and ``childb_set`` for the ``ChildB`` field. |
|---|
| | 2191 | |
|---|
| | 2192 | Multi-table inheritance |
|---|
| | 2193 | ----------------------- |
|---|
| | 2194 | |
|---|
| | 2195 | The second type of model inheritance supported by Django is when each model in |
|---|
| | 2196 | the hierarchy is a model all by itself. Each model corresponds to its own |
|---|
| | 2197 | database table and can be queried and created indvidually. The inheritance |
|---|
| | 2198 | relationship introduces links between the child model and each of its parents |
|---|
| | 2199 | (via an automatically created ``OneToOneField``). For example:: |
|---|
| | 2200 | |
|---|
| | 2201 | class Place(models.Model): |
|---|
| | 2202 | name = models.CharField(max_length=50) |
|---|
| | 2203 | address = models.CharField(max_length=80) |
|---|
| | 2204 | |
|---|
| | 2205 | class Restaurant(Place): |
|---|
| | 2206 | serves_hot_dogs = models.BooleanField() |
|---|
| | 2207 | serves_pizza = models.BooleanField() |
|---|
| | 2208 | |
|---|
| | 2209 | All of the fields of ``Place`` will also be available in ``Restaurant``, |
|---|
| | 2210 | although the data will reside in a different database table. So these are both |
|---|
| | 2211 | possible:: |
|---|
| | 2212 | |
|---|
| | 2213 | >>> Place.objects.filter(name="Bob's Cafe") |
|---|
| | 2214 | >>> Restaurant.objects.filter(name="Bob's Cafe") |
|---|
| | 2215 | |
|---|
| | 2216 | If you have a ``Place`` that is also a ``Restaurant``, you can get from the |
|---|
| | 2217 | ``Place`` object to the ``Restaurant`` object by using the lower-case version |
|---|
| | 2218 | of the model name:: |
|---|
| | 2219 | |
|---|
| | 2220 | >>> p = Place.objects.filter(name="Bob's Cafe") |
|---|
| | 2221 | # If Bob's Cafe is a Restaurant object, this will give the child class: |
|---|
| | 2222 | >>> p.restaurant |
|---|
| | 2223 | <Restaurant: ...> |
|---|
| | 2224 | |
|---|
| | 2225 | However, if ``p`` in the above example was *not* a ``Restaurant`` (it had been |
|---|
| | 2226 | created directly as a ``Place`` object or was the parent of some other class), |
|---|
| | 2227 | referring to ``p.restaurant`` would give an error. |
|---|
| | 2228 | |
|---|
| | 2229 | ``Meta`` and multi-table inheritance |
|---|
| | 2230 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| | 2231 | |
|---|
| | 2232 | In the multi-table inheritance situation, it doesn't make sense for a child |
|---|
| | 2233 | class to inherit from its parent's ``Meta`` class. All the ``Meta`` options |
|---|
| | 2234 | have already been applied to the parent class and applying them again would |
|---|
| | 2235 | normally only lead to contradictory behaviour (this is in contrast with the |
|---|
| | 2236 | abstract base class case, where the base class doesn't exist in its own |
|---|
| | 2237 | right). |
|---|
| | 2238 | |
|---|
| | 2239 | So a child model does not have access to its parent's ``Meta`` class. However, |
|---|
| | 2240 | there are a few limited cases where the child inherits behaviour from the |
|---|
| | 2241 | parent: if the child does not specify an ``ordering`` attribute or a |
|---|
| | 2242 | ``get_latest_by`` attribute, it will inherit these from its parent. |
|---|
| | 2243 | |
|---|
| | 2244 | If the parent has an ordering and you don't want the child to have any natural |
|---|
| | 2245 | ordering, you can explicity set it to be empty:: |
|---|
| | 2246 | |
|---|
| | 2247 | class ChildModel(ParentModel): |
|---|
| | 2248 | ... |
|---|
| | 2249 | class Meta: |
|---|
| | 2250 | # Remove parent's ordering effect |
|---|
| | 2251 | ordering = [] |
|---|
| | 2252 | |
|---|
| | 2253 | Inheritance and reverse relations |
|---|
| | 2254 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| | 2255 | |
|---|
| | 2256 | Because multi-table inheritance uses an implicit ``OneToOneField`` to link the |
|---|
| | 2257 | child and the parent, it's possible to move from the parent down to the child, |
|---|
| | 2258 | as in the above example. However, this uses up the name that is the default |
|---|
| | 2259 | ``related_name`` value for ``ForeignKey`` and ``ManyToManyField`` relations. |
|---|
| | 2260 | If you are putting those type of relations on a subclass of another model, you |
|---|
| | 2261 | **must** specify the ``related_name`` attribute on each such field. If you |
|---|
| | 2262 | forget, Django will raise an error when you run ``manage.py validate`` or try |
|---|
| | 2263 | to syncdb. |
|---|
| | 2264 | |
|---|
| | 2265 | For example, using the above ``Place`` class again, let's create another |
|---|
| | 2266 | subclass with a ``ManyToManyField``:: |
|---|
| | 2267 | |
|---|
| | 2268 | class Supplier(Place): |
|---|
| | 2269 | # Must specify related_name on all relations. |
|---|
| | 2270 | customers = models.ManyToManyField(Restaurant, |
|---|
| | 2271 | related_name='provider') |
|---|
| | 2272 | |
|---|
| | 2273 | For more information about reverse relations, refer to the `Database API |
|---|
| | 2274 | reference`_ . For now, just remember to run ``manage.py validate`` when |
|---|
| | 2275 | you're writing your models and pay attention to the error messages. |
|---|
| | 2276 | |
|---|
| | 2277 | Specifying the parent link field |
|---|
| | 2278 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| | 2279 | |
|---|
| | 2280 | As mentioned, Django will automatically create a ``OneToOneField`` linking |
|---|
| | 2281 | your child class back any non-abstract parent models. If you want to control |
|---|
| | 2282 | the name of the attribute linking back to the parent, you can create your own |
|---|
| | 2283 | link field and pass it ``parent_link=True``. For example, to explicitly |
|---|
| | 2284 | specify the field that will link ``Supplier`` to ``Place`` in the above |
|---|
| | 2285 | example, you could write:: |
|---|
| | 2286 | |
|---|
| | 2287 | class Supplier(Place): |
|---|
| | 2288 | parent = models.OneToOneField(Place, parent_link=True) |
|---|
| | 2289 | ... |
|---|
| | 2290 | |
|---|
| | 2291 | Multiple inheritance |
|---|
| | 2292 | -------------------- |
|---|
| | 2293 | |
|---|
| | 2294 | Just as with Python's subclassing, it's possible for a Django model to inherit |
|---|
| | 2295 | from multiple parent models. Keep in mind that normal Python name resolution |
|---|
| | 2296 | rules apply. The first base class that a particular name appears in (e.g. |
|---|
| | 2297 | ``Meta``) will be the one that is used. We stop searching once we find the |
|---|
| | 2298 | name once. This means that if multiple parents contain a ``Meta`` class, only |
|---|
| | 2299 | the first one is going to be used. All others will be ignored. |
|---|
| | 2300 | |
|---|
| | 2301 | Generally, you won't need to inherit from multiple parents. The main use-case |
|---|
| | 2302 | where this is useful is for ''mix-in'' classes: adding a particular extra |
|---|
| | 2303 | field or method to every class that inherits the mix-in. Try to keep your |
|---|
| | 2304 | inheritance hierarchies as simple and straightforward as possible so that you |
|---|
| | 2305 | won't have to struggle to work out where a particular piece of information is |
|---|
| | 2306 | coming from. |
|---|
| | 2307 | |
|---|