PageRenderTime 160ms CodeModel.GetById 81ms app.highlight 3ms RepoModel.GetById 71ms app.codeStats 0ms

/docs/topics/db/managers.txt

https://code.google.com/p/mango-py/
Plain Text | 398 lines | 303 code | 95 blank | 0 comment | 0 complexity | 9a540ac5e8f459f3e352e3859b764953 MD5 | raw file
  1========
  2Managers
  3========
  4
  5.. currentmodule:: django.db.models
  6
  7.. class:: Manager()
  8
  9A ``Manager`` is the interface through which database query operations are
 10provided to Django models. At least one ``Manager`` exists for every model in
 11a Django application.
 12
 13The way ``Manager`` classes work is documented in :doc:`/topics/db/queries`;
 14this document specifically touches on model options that customize ``Manager``
 15behavior.
 16
 17.. _manager-names:
 18
 19Manager names
 20=============
 21
 22By default, Django adds a ``Manager`` with the name ``objects`` to every Django
 23model class. However, if you want to use ``objects`` as a field name, or if you
 24want to use a name other than ``objects`` for the ``Manager``, you can rename
 25it on a per-model basis. To rename the ``Manager`` for a given class, define a
 26class attribute of type ``models.Manager()`` on that model. For example::
 27
 28    from django.db import models
 29
 30    class Person(models.Model):
 31        #...
 32        people = models.Manager()
 33
 34Using this example model, ``Person.objects`` will generate an
 35``AttributeError`` exception, but ``Person.people.all()`` will provide a list
 36of all ``Person`` objects.
 37
 38.. _custom-managers:
 39
 40Custom Managers
 41===============
 42
 43You can use a custom ``Manager`` in a particular model by extending the base
 44``Manager`` class and instantiating your custom ``Manager`` in your model.
 45
 46There are two reasons you might want to customize a ``Manager``: to add extra
 47``Manager`` methods, and/or to modify the initial ``QuerySet`` the ``Manager``
 48returns.
 49
 50Adding extra Manager methods
 51----------------------------
 52
 53Adding extra ``Manager`` methods is the preferred way to add "table-level"
 54functionality to your models. (For "row-level" functionality -- i.e., functions
 55that act on a single instance of a model object -- use :ref:`Model methods
 56<model-methods>`, not custom ``Manager`` methods.)
 57
 58A custom ``Manager`` method can return anything you want. It doesn't have to
 59return a ``QuerySet``.
 60
 61For example, this custom ``Manager`` offers a method ``with_counts()``, which
 62returns a list of all ``OpinionPoll`` objects, each with an extra
 63``num_responses`` attribute that is the result of an aggregate query::
 64
 65    class PollManager(models.Manager):
 66        def with_counts(self):
 67            from django.db import connection
 68            cursor = connection.cursor()
 69            cursor.execute("""
 70                SELECT p.id, p.question, p.poll_date, COUNT(*)
 71                FROM polls_opinionpoll p, polls_response r
 72                WHERE p.id = r.poll_id
 73                GROUP BY 1, 2, 3
 74                ORDER BY 3 DESC""")
 75            result_list = []
 76            for row in cursor.fetchall():
 77                p = self.model(id=row[0], question=row[1], poll_date=row[2])
 78                p.num_responses = row[3]
 79                result_list.append(p)
 80            return result_list
 81
 82    class OpinionPoll(models.Model):
 83        question = models.CharField(max_length=200)
 84        poll_date = models.DateField()
 85        objects = PollManager()
 86
 87    class Response(models.Model):
 88        poll = models.ForeignKey(Poll)
 89        person_name = models.CharField(max_length=50)
 90        response = models.TextField()
 91
 92With this example, you'd use ``OpinionPoll.objects.with_counts()`` to return
 93that list of ``OpinionPoll`` objects with ``num_responses`` attributes.
 94
 95Another thing to note about this example is that ``Manager`` methods can
 96access ``self.model`` to get the model class to which they're attached.
 97
 98Modifying initial Manager QuerySets
 99-----------------------------------
100
101A ``Manager``'s base ``QuerySet`` returns all objects in the system. For
102example, using this model::
103
104    class Book(models.Model):
105        title = models.CharField(max_length=100)
106        author = models.CharField(max_length=50)
107
108...the statement ``Book.objects.all()`` will return all books in the database.
109
110You can override a ``Manager``\'s base ``QuerySet`` by overriding the
111``Manager.get_query_set()`` method. ``get_query_set()`` should return a
112``QuerySet`` with the properties you require.
113
114For example, the following model has *two* ``Manager``\s -- one that returns
115all objects, and one that returns only the books by Roald Dahl::
116
117    # First, define the Manager subclass.
118    class DahlBookManager(models.Manager):
119        def get_query_set(self):
120            return super(DahlBookManager, self).get_query_set().filter(author='Roald Dahl')
121
122    # Then hook it into the Book model explicitly.
123    class Book(models.Model):
124        title = models.CharField(max_length=100)
125        author = models.CharField(max_length=50)
126
127        objects = models.Manager() # The default manager.
128        dahl_objects = DahlBookManager() # The Dahl-specific manager.
129
130With this sample model, ``Book.objects.all()`` will return all books in the
131database, but ``Book.dahl_objects.all()`` will only return the ones written by
132Roald Dahl.
133
134Of course, because ``get_query_set()`` returns a ``QuerySet`` object, you can
135use ``filter()``, ``exclude()`` and all the other ``QuerySet`` methods on it.
136So these statements are all legal::
137
138    Book.dahl_objects.all()
139    Book.dahl_objects.filter(title='Matilda')
140    Book.dahl_objects.count()
141
142This example also pointed out another interesting technique: using multiple
143managers on the same model. You can attach as many ``Manager()`` instances to
144a model as you'd like. This is an easy way to define common "filters" for your
145models.
146
147For example::
148
149    class MaleManager(models.Manager):
150        def get_query_set(self):
151            return super(MaleManager, self).get_query_set().filter(sex='M')
152
153    class FemaleManager(models.Manager):
154        def get_query_set(self):
155            return super(FemaleManager, self).get_query_set().filter(sex='F')
156
157    class Person(models.Model):
158        first_name = models.CharField(max_length=50)
159        last_name = models.CharField(max_length=50)
160        sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female')))
161        people = models.Manager()
162        men = MaleManager()
163        women = FemaleManager()
164
165This example allows you to request ``Person.men.all()``, ``Person.women.all()``,
166and ``Person.people.all()``, yielding predictable results.
167
168If you use custom ``Manager`` objects, take note that the first ``Manager``
169Django encounters (in the order in which they're defined in the model) has a
170special status. Django interprets the first ``Manager`` defined in a class as
171the "default" ``Manager``, and several parts of Django
172(including :djadmin:`dumpdata`) will use that ``Manager``
173exclusively for that model. As a result, it's a good idea to be careful in
174your choice of default manager in order to avoid a situation where overriding
175``get_query_set()`` results in an inability to retrieve objects you'd like to
176work with.
177
178.. _managers-for-related-objects:
179
180Using managers for related object access
181~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
182
183By default, Django uses an instance of a "plain" manager class when accessing
184related objects (i.e. ``choice.poll``), not the default manager on the related
185object. This is because Django needs to be able to retrieve the related
186object, even if it would otherwise be filtered out (and hence be inaccessible)
187by the default manager.
188
189If the normal plain manager class (:class:`django.db.models.Manager`) is not
190appropriate for your circumstances, you can force Django to use the same class
191as the default manager for your model by setting the `use_for_related_fields`
192attribute on the manager class. This is documented fully below_.
193
194.. _below: manager-types_
195
196.. _custom-managers-and-inheritance:
197
198Custom managers and model inheritance
199-------------------------------------
200
201Class inheritance and model managers aren't quite a perfect match for each
202other. Managers are often specific to the classes they are defined on and
203inheriting them in subclasses isn't necessarily a good idea. Also, because the
204first manager declared is the *default manager*, it is important to allow that
205to be controlled. So here's how Django handles custom managers and
206:ref:`model inheritance <model-inheritance>`:
207
208    1. Managers defined on non-abstract base classes are *not* inherited by
209       child classes. If you want to reuse a manager from a non-abstract base,
210       redeclare it explicitly on the child class. These sorts of managers are
211       likely to be fairly specific to the class they are defined on, so
212       inheriting them can often lead to unexpected results (particularly as
213       far as the default manager goes). Therefore, they aren't passed onto
214       child classes.
215
216    2. Managers from abstract base classes are always inherited by the child
217       class, using Python's normal name resolution order (names on the child
218       class override all others; then come names on the first parent class,
219       and so on). Abstract base classes are designed to capture information
220       and behavior that is common to their child classes. Defining common
221       managers is an appropriate part of this common information.
222
223    3. The default manager on a class is either the first manager declared on
224       the class, if that exists, or the default manager of the first abstract
225       base class in the parent hierarchy, if that exists. If no default
226       manager is explicitly declared, Django's normal default manager is
227       used.
228
229These rules provide the necessary flexibility if you want to install a
230collection of custom managers on a group of models, via an abstract base
231class, but still customize the default manager. For example, suppose you have
232this base class::
233
234    class AbstractBase(models.Model):
235        ...
236        objects = CustomManager()
237
238        class Meta:
239            abstract = True
240
241If you use this directly in a subclass, ``objects`` will be the default
242manager 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
248If you want to inherit from ``AbstractBase``, but provide a different default
249manager, 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
256Here, ``default_manager`` is the default. The ``objects`` manager is
257still available, since it's inherited. It just isn't used as the default.
258
259Finally for this example, suppose you want to add extra managers to the child
260class, but still use the default from ``AbstractBase``. You can't add the new
261manager directly in the child class, as that would override the default and you would
262have to also explicitly include all the managers from the abstract base class.
263The solution is to put the extra managers in another base class and introduce
264it 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
277Implementation concerns
278-----------------------
279
280Whatever features you add to your custom ``Manager``, it must be
281possible to make a shallow copy of a ``Manager`` instance; i.e., the
282following code must work::
283
284    >>> import copy
285    >>> manager = MyManager()
286    >>> my_copy = copy.copy(manager)
287
288Django makes shallow copies of manager objects during certain queries;
289if your Manager cannot be copied, those queries will fail.
290
291This won't be an issue for most custom managers. If you are just
292adding simple methods to your ``Manager``, it is unlikely that you
293will inadvertently make instances of your ``Manager`` uncopyable.
294However, if you're overriding ``__getattr__`` or some other private
295method of your ``Manager`` object that controls object state, you
296should ensure that you don't affect the ability of your ``Manager`` to
297be copied.
298
299.. _manager-types:
300
301Controlling automatic Manager types
302===================================
303
304This document has already mentioned a couple of places where Django creates a
305manager class for you: `default managers`_ and the "plain" manager used to
306`access related objects`_. There are other places in the implementation of
307Django where temporary plain managers are needed. Those automatically created
308managers will normally be instances of the :class:`django.db.models.Manager`
309class.
310
311.. _default managers: manager-names_
312.. _access related objects: managers-for-related-objects_
313
314Throughout this section, we will use the term "automatic manager" to mean a
315manager that Django creates for you -- either as a default manager on a model
316with no managers, or to use temporarily when accessing related objects.
317
318Sometimes this default class won't be the right choice. One example is in the
319:mod:`django.contrib.gis` application that ships with Django itself. All ``gis``
320models must use a special manager class (:class:`~django.contrib.gis.db.models.GeoManager`)
321because they need a special queryset (:class:`~django.contrib.gis.db.models.GeoQuerySet`)
322to be used for interacting with the database.  It turns out that models which require
323a special manager like this need to use the same manager class wherever an automatic
324manager is created.
325
326Django provides a way for custom manager developers to say that their manager
327class should be used for automatic managers whenever it is the default manager
328on a model. This is done by setting the ``use_for_related_fields`` attribute on
329the manager class::
330
331    class MyManager(models.Manager):
332        use_for_related_fields = True
333
334        ...
335
336If this attribute is set on the *default* manager for a model (only the
337default manager is considered in these situations), Django will use that class
338whenever it needs to automatically create a manager for the class.  Otherwise,
339it will use :class:`django.db.models.Manager`.
340
341.. admonition:: Historical Note
342
343    Given the purpose for which it's used, the name of this attribute
344    (``use_for_related_fields``) might seem a little odd. Originally, the
345    attribute only controlled the type of manager used for related field
346    access, which is where the name came from. As it became clear the concept
347    was more broadly useful, the name hasn't been changed. This is primarily
348    so that existing code will :doc:`continue to work </misc/api-stability>` in
349    future Django versions.
350
351Writing correct Managers for use in automatic Manager instances
352---------------------------------------------------------------
353
354As already suggested by the `django.contrib.gis` example, above, the
355``use_for_related_fields`` feature is primarily for managers that need to
356return a custom ``QuerySet`` subclass. In providing this functionality in your
357manager, there are a couple of things to remember.
358
359Do not filter away any results in this type of manager subclass
360~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
361
362One reason an automatic manager is used is to access objects that are related
363to from some other model. In those situations, Django has to be able to see
364all the objects for the model it is fetching, so that *anything* which is
365referred to can be retrieved.
366
367If you override the ``get_query_set()`` method and filter out any rows, Django
368will return incorrect results. Don't do that. A manager that filters results
369in ``get_query_set()`` is not appropriate for use as an automatic manager.
370
371Set ``use_for_related_fields`` when you define the class
372~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
373
374The ``use_for_related_fields`` attribute must be set on the manager *class*, not
375on an *instance* of the class. The earlier example shows the correct way to set
376it, whereas the following will not work::
377
378    # BAD: Incorrect code
379    class MyManager(models.Manager):
380        ...
381
382    # Sets the attribute on an instance of MyManager. Django will
383    # ignore this setting.
384    mgr = MyManager()
385    mgr.use_for_related_fields = True
386
387    class MyModel(models.Model):
388        ...
389        objects = mgr
390
391    # End of incorrect code.
392
393You also shouldn't change the attribute on the class object after it has been
394used in a model, since the attribute's value is processed when the model class
395is created and not subsequently reread. Set the attribute on the manager class
396when it is first defined, as in the initial example of this section and
397everything will work smoothly.
398