mirror of https://github.com/django/django.git
Documented patterns for adding extra managers to model subclasses.
This seems to have been a source of confusion, so now we have some explicit examples. Fixed #9676. git-svn-id: http://code.djangoproject.com/svn/django/trunk@10058 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
292f503845
commit
24b9c65d3f
|
@ -217,7 +217,7 @@ to be controlled. So here's how Django handles custom managers and
|
|||
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 behaviour that is common to their child classes. Defining common
|
||||
and behavior that is common to their child classes. Defining common
|
||||
managers is an appropriate part of this common information.
|
||||
|
||||
3. The default manager on a class is either the first manager declared on
|
||||
|
@ -226,6 +226,54 @@ to be controlled. So here's how Django handles custom managers and
|
|||
manager is explicitly declared, Django's normal default manager is
|
||||
used.
|
||||
|
||||
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
|
||||
class, but still customize the default manager. For example, suppose you have
|
||||
this base class::
|
||||
|
||||
class AbstractBase(models.Model):
|
||||
...
|
||||
objects = CustomerManager()
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
If you use this directly in a subclass, ``objects`` will be the default
|
||||
manager if you declare no managers in the base class::
|
||||
|
||||
class ChildA(AbstractBase):
|
||||
...
|
||||
# This class has CustomManager as the default manager.
|
||||
|
||||
If you want to inherit from ``AbstractBase``, but provide a different default
|
||||
manager, you can provide the default manager on the child class::
|
||||
|
||||
class ChildB(AbstractBase):
|
||||
...
|
||||
# An explicit default manager.
|
||||
default_manager = OtherManager()
|
||||
|
||||
Here, ``default_manager`` is the default. The ``objects`` manager is
|
||||
still available, since it's inherited. It just isn't used as the default.
|
||||
|
||||
Finally for this example, suppose you want to add extra managers to the child
|
||||
class, but still use the default from ``AbstractBase``. You can't add the new
|
||||
manager directly in the child class, as that would override the default and you would
|
||||
have to also explicitly include all the managers from the abstract base class.
|
||||
The solution is to put the extra managers in another base class and introduce
|
||||
it into the inheritance hierarchy *after* the defaults::
|
||||
|
||||
class ExtraManager(models.Model):
|
||||
extra_manager = OtherManager()
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
class ChildC(AbstractBase, ExtraManager):
|
||||
...
|
||||
# Default manager is CustomManager, but OtherManager is
|
||||
# also available via the "extra_manager" attribute.
|
||||
|
||||
.. _manager-types:
|
||||
|
||||
Controlling Automatic Manager Types
|
||||
|
|
Loading…
Reference in New Issue