diff options
| author | Loïc Bistuer <loic.bistuer@gmail.com> | 2016-02-19 02:27:55 +0700 |
|---|---|---|
| committer | Loïc Bistuer <loic.bistuer@gmail.com> | 2016-05-17 02:29:22 +0700 |
| commit | 3a47d42fa33012b2156bf04058d933df6b3082d2 (patch) | |
| tree | ed1ab104835ed71551eaccd7253e7b520c5e8d0c /docs | |
| parent | 9935f97cd203bdcc722bc3d4e96858e221d96ff8 (diff) | |
Fixed #20932, #25897 -- Streamlined manager inheritance.
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/topics/db/managers.txt | 39 | ||||
| -rw-r--r-- | docs/topics/db/models.txt | 32 |
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``. |
