Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[1.0.X] Documented patterns for adding extra managers to model subcla…

…sses.

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
  • Loading branch information...
commit 4d6763128f6f4e46982ae841a3f9962e07507c64 1 parent 8a0a176
Malcolm Tredinnick authored March 15, 2009

Showing 1 changed file with 49 additions and 1 deletion. Show diff stats Hide diff stats

  1. 50  docs/topics/db/managers.txt
50  docs/topics/db/managers.txt
@@ -217,7 +217,7 @@ to be controlled. So here's how Django handles custom managers and
217 217
        class, using Python's normal name resolution order (names on the child
218 218
        class override all others; then come names on the first parent class,
219 219
        and so on). Abstract base classes are designed to capture information
220  
-       and behaviour that is common to their child classes. Defining common
  220
+       and behavior that is common to their child classes. Defining common
221 221
        managers is an appropriate part of this common information.
222 222
 
223 223
     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
226 226
        manager is explicitly declared, Django's normal default manager is
227 227
        used.
228 228
 
  229
+These rules provide the necessary flexibility if you want to install a
  230
+collection of custom managers on a group of models, via an abstract base
  231
+class, but still customize the default manager. For example, suppose you have
  232
+this base class::
  233
+
  234
+    class AbstractBase(models.Model):
  235
+        ...
  236
+        objects = CustomerManager()
  237
+
  238
+        class Meta:
  239
+            abstract = True
  240
+
  241
+If you use this directly in a subclass, ``objects`` will be the default
  242
+manager if you declare no managers in the base class::
  243
+
  244
+    class ChildA(AbstractBase):
  245
+        ...
  246
+        # This class has CustomManager as the default manager.
  247
+
  248
+If you want to inherit from ``AbstractBase``, but provide a different default
  249
+manager, you can provide the default manager on the child class::
  250
+
  251
+    class ChildB(AbstractBase):
  252
+        ...
  253
+        # An explicit default manager.
  254
+        default_manager = OtherManager()
  255
+
  256
+Here, ``default_manager`` is the default. The ``objects`` manager is
  257
+still available, since it's inherited. It just isn't used as the default.
  258
+
  259
+Finally for this example, suppose you want to add extra managers to the child
  260
+class, but still use the default from ``AbstractBase``. You can't add the new
  261
+manager directly in the child class, as that would override the default and you would
  262
+have to also explicitly include all the managers from the abstract base class.
  263
+The solution is to put the extra managers in another base class and introduce
  264
+it into the inheritance hierarchy *after* the defaults::
  265
+
  266
+    class ExtraManager(models.Model):
  267
+        extra_manager = OtherManager()
  268
+
  269
+        class Meta:
  270
+            abstract = True
  271
+
  272
+    class ChildC(AbstractBase, ExtraManager):
  273
+        ...
  274
+        # Default manager is CustomManager, but OtherManager is
  275
+        # also available via the "extra_manager" attribute.
  276
+
229 277
 .. _manager-types:
230 278
 
231 279
 Controlling Automatic Manager Types

0 notes on commit 4d67631

Please sign in to comment.
Something went wrong with that request. Please try again.