summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/model-api.txt86
1 files changed, 84 insertions, 2 deletions
diff --git a/docs/model-api.txt b/docs/model-api.txt
index 6ca08ae4e5..2687c00d14 100644
--- a/docs/model-api.txt
+++ b/docs/model-api.txt
@@ -2031,6 +2031,18 @@ You can also prevent saving::
Model inheritance
=================
+**New in Django development version**
+
+Model inheritance in Django works almost identically to the way normal class
+inheritance works in Python. The only decision you have to make is whether you
+want the parent models to be models in their own right (with their own
+database tables), or if the parents are just holders of common information
+that will only be visible through the child models.
+
+Often, you will just want to use the parent class to hold information that you
+don't want to have to type out for each child model. This class isn't going to
+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.
+
Abstract base classes
---------------------
@@ -2063,6 +2075,38 @@ For many uses, this type of model inheritance will be exactly what you want.
It provides a way to factor out common information at the Python level, whilst
still only creating one database table per child model at the database level.
+``Meta`` inheritance
+~~~~~~~~~~~~~~~~~~~~
+
+When an abstract base class is created, Django makes any ``Meta`` inner class
+you declared on the base class available as an attribute. If a child class
+does not declared its own ``Meta`` class, it will inherit the parent's
+``Meta``. If the child wants to extend the parent's ``Meta`` class, it can
+subclass it. For example::
+
+ class CommonInfo(models.Model):
+ ...
+ class Meta:
+ abstract = True
+ ordering = ['name']
+
+ class Student(CommonInfo):
+ ...
+ class Meta(CommonInfo.Meta):
+ db_table = 'student_info'
+
+Django does make one adjustment to the ``Meta`` class of an abstract base
+class: before installing the ``Meta`` attribute, it sets ``abstract=False``.
+This means that children of abstract base classes don't automatically become
+abstract classes themselves. Of course, you can make an abstract base class
+that inherits from another abstract base class. You just need to remember to
+explicitly set ``abstract=True`` each time.
+
+Some attributes won't make sense to include in the ``Meta`` class of an
+abstract base class. For example, including ``db_table`` would mean that all
+the child classes (the ones that don't specify their own ``Meta``) would use
+the same database table, which is almost certainly not what you want.
+
Multi-table inheritance
-----------------------
@@ -2100,8 +2144,29 @@ However, if ``p`` in the above example was *not* a ``Restaurant`` (it had been
created directly as a ``Place`` object or was the parent of some other class),
referring to ``p.restaurant`` would give an error.
-Normally you won't need to worry too much about how model inheritance works.
-It will behave similarly to Python class inheritance.
+``Meta`` and multi-table inheritance
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In the multi-table inheritance situation, it doesn't make sense for a child
+class to inherit from its parent's ``Meta`` class. All the ``Meta`` options
+have already been applied to the parent class and applying them again would
+normally only lead to contradictory behaviour (this is in contrast with the
+abstract base class case, where the base class doesn't exist in its own
+right).
+
+So a child model does not have access to its parent's ``Meta`` class. However,
+there are a few limited cases where the child inherits behaviour from the
+parent: if the child does not specify an ``ordering`` attribute or a
+``get_latest_by`` attribute, it will inherit these from its parent.
+
+If the parent has an ordering and you don't want the child to have any natural
+ordering, you can explicity set it to be empty::
+
+ class ChildModel(ParentModel):
+ ...
+ class Meta:
+ # Remove parent's ordering effect
+ ordering = []
Inheritance and reverse relations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2127,6 +2192,23 @@ For more information about reverse relations, refer to the `Database API
reference`_ . For now, just remember to run ``manage.py validate`` when
you're writing your models and pay attention to the error messages.
+Multiple inheritance
+--------------------
+
+Just as with Python's subclassing, it's possible for a Django model to inherit
+from multiple parent models. Keep in mind that normal Python name resolution
+rules apply. The first base class that a particular name appears in (e.g.
+``Meta``) will be the one that is used. We stop searching once we find the
+name once. This means that if multiple parents contain a ``Meta`` class, only
+the first one is going to be used. All others will be ignored.
+
+Generally, you won't need to inherit from multiple parents. The main use-case
+where this is useful is for ''mix-in'' classes: adding a particular extra
+field or method to every class that inherits the mix-in. Try to keep your
+inheritance hierarchies as simple and straightforward as possible so that you
+won't have to struggle to work out where a particular piece of information is
+coming from.
+
Models across files
===================