summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorLoïc Bistuer <loic.bistuer@gmail.com>2016-02-19 02:27:55 +0700
committerLoïc Bistuer <loic.bistuer@gmail.com>2016-05-17 02:29:22 +0700
commit3a47d42fa33012b2156bf04058d933df6b3082d2 (patch)
treeed1ab104835ed71551eaccd7253e7b520c5e8d0c /docs
parent9935f97cd203bdcc722bc3d4e96858e221d96ff8 (diff)
Fixed #20932, #25897 -- Streamlined manager inheritance.
Diffstat (limited to 'docs')
-rw-r--r--docs/topics/db/managers.txt39
-rw-r--r--docs/topics/db/models.txt32
2 files changed, 25 insertions, 46 deletions
diff --git a/docs/topics/db/managers.txt b/docs/topics/db/managers.txt
index a82b78e1a0..80598f0c98 100644
--- a/docs/topics/db/managers.txt
+++ b/docs/topics/db/managers.txt
@@ -321,33 +321,26 @@ You may also store the generated class into a variable::
Custom managers and model inheritance
-------------------------------------
-Class inheritance and model managers aren't quite a perfect match for each
-other. Managers are often specific to the classes they are defined on and
-inheriting them in subclasses isn't necessarily a good idea. Also, because the
-first manager declared is the *default manager*, it is important to allow that
-to be controlled. So here's how Django handles custom managers and
+Here's how Django handles custom managers and
:ref:`model inheritance <model-inheritance>`:
-1. Managers defined on non-abstract base classes are *not* inherited by
- child classes. If you want to reuse a manager from a non-abstract base,
- redeclare it explicitly on the child class. These sorts of managers are
- likely to be fairly specific to the class they are defined on, so
- inheriting them can often lead to unexpected results (particularly as
- far as the default manager goes). Therefore, they aren't passed onto
- child classes.
-
-2. Managers from abstract base classes are always inherited by the child
- class, using Python's normal name resolution order (names on the child
+1. Managers from base classes are always inherited by the child class,
+ using Python's normal name resolution order (names on the child
class override all others; then come names on the first parent class,
- and so on). Abstract base classes are designed to capture information
- and behavior that is common to their child classes. Defining common
- managers is an appropriate part of this common information.
+ and so on).
+
+2. The default manager on a class is either the first manager declared on the
+ class, if that exists, or the default manager of the first parent class in
+ the parent hierarchy, if that exists. If no manager is explicitly declared,
+ Django automatically creates the `objects` manager and it becomes the default
+ manager.
+
+.. versionchanged:: 1.10
-3. The default manager on a class is either the first manager declared on
- the class, if that exists, or the default manager of the first abstract
- base class in the parent hierarchy, if that exists. If no default
- manager is explicitly declared, Django's normal default manager is
- used.
+ In older versions, manager inheritance varied depending on the type of
+ model inheritance (i.e. :ref:`abstract-base-classes`,
+ :ref:`multi-table-inheritance`, or :ref:`proxy-models`), especially
+ with regards to electing the default manager.
These rules provide the necessary flexibility if you want to install a
collection of custom managers on a group of models, via an abstract base
diff --git a/docs/topics/db/models.txt b/docs/topics/db/models.txt
index 1dc1b17202..69562f6544 100644
--- a/docs/topics/db/models.txt
+++ b/docs/topics/db/models.txt
@@ -1287,33 +1287,19 @@ Differences between proxy inheritance and unmanaged models
Proxy model inheritance might look fairly similar to creating an unmanaged
model, using the :attr:`~django.db.models.Options.managed` attribute on a
-model's ``Meta`` class. The two alternatives are not quite the same and it's
-worth considering which one you should use.
+model's ``Meta`` class.
-One difference is that you can (and, in fact, must unless you want an empty
-model) specify model fields on models with ``Meta.managed=False``. You could,
-with careful setting of :attr:`Meta.db_table
-<django.db.models.Options.db_table>` create an unmanaged model that shadowed
-an existing model and add Python methods to it. However, that would be very
-repetitive and fragile as you need to keep both copies synchronized if you
+With careful setting of :attr:`Meta.db_table
+<django.db.models.Options.db_table>` you could create an unmanaged model that
+shadows an existing model and adds Python methods to it. However, that would be
+very repetitive and fragile as you need to keep both copies synchronized if you
make any changes.
-The other difference that is more important for proxy models, is how model
-managers are handled. Proxy models are intended to behave exactly like the
-model they are proxying for. So they inherit the parent model's managers,
-including the default manager. In the normal multi-table model inheritance
-case, children do not inherit managers from their parents as the custom
-managers aren't always appropriate when extra fields are involved. The
-:ref:`manager documentation <custom-managers-and-inheritance>` has more
-details about this latter case.
+On the other hand, proxy models are intended to behave exactly like the model
+they are proxying for. They are always in sync with the parent model since they
+directly inherit its fields and managers.
-When these two features were implemented, attempts were made to squash them
-into a single option. It turned out that interactions with inheritance, in
-general, and managers, in particular, made the API very complicated and
-potentially difficult to understand and use. It turned out that two options
-were needed in any case, so the current separation arose.
-
-So, the general rules are:
+The general rules are:
1. If you are mirroring an existing model or database table and don't want
all the original database table columns, use ``Meta.managed=False``.