summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2009-03-15 03:46:26 +0000
committerMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2009-03-15 03:46:26 +0000
commit4d6763128f6f4e46982ae841a3f9962e07507c64 (patch)
tree775001157e298850d5ac4a0bc07ff4427089b787 /docs
parent8a0a17628b4a3f5e7ed1d8dff3186e5ece573f0a (diff)
[1.0.X] 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. Backport of r10058 from trunk. git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.0.X@10061 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'docs')
-rw-r--r--docs/topics/db/managers.txt50
1 files changed, 49 insertions, 1 deletions
diff --git a/docs/topics/db/managers.txt b/docs/topics/db/managers.txt
index 102ff5036a..2ace9c1408 100644
--- a/docs/topics/db/managers.txt
+++ b/docs/topics/db/managers.txt
@@ -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