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, using Python's normal name resolution order (names on the child
|
||||||
class override all others; then come names on the first parent class,
|
class override all others; then come names on the first parent class,
|
||||||
and so on). Abstract base classes are designed to capture information
|
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.
|
managers is an appropriate part of this common information.
|
||||||
|
|
||||||
3. The default manager on a class is either the first manager declared on
|
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
|
manager is explicitly declared, Django's normal default manager is
|
||||||
used.
|
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:
|
.. _manager-types:
|
||||||
|
|
||||||
Controlling Automatic Manager Types
|
Controlling Automatic Manager Types
|
||||||
|
|
Loading…
Reference in New Issue