Clarified and expanded documentation for Manager.use_for_related_fields.
This is for Manager subclasses that are default managers, but only sometimes. The general rule is: "don't use it." If you really need it, read the instructions. git-svn-id: http://code.djangoproject.com/svn/django/trunk@10057 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
7d9b29a56d
commit
292f503845
|
@ -16,6 +16,8 @@ The way ``Manager`` classes work is documented :ref:`topics-db-queries`; this
|
||||||
document specifically touches on model options that customize ``Manager``
|
document specifically touches on model options that customize ``Manager``
|
||||||
behavior.
|
behavior.
|
||||||
|
|
||||||
|
.. _manager-names:
|
||||||
|
|
||||||
Manager names
|
Manager names
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
@ -175,20 +177,23 @@ good idea to be careful in your choice of default manager, in order to
|
||||||
avoid a situation where overriding of ``get_query_set()`` results in
|
avoid a situation where overriding of ``get_query_set()`` results in
|
||||||
an inability to retrieve objects you'd like to work with.
|
an inability to retrieve objects you'd like to work with.
|
||||||
|
|
||||||
|
.. _managers-for-related-objects:
|
||||||
|
|
||||||
Using managers for related object access
|
Using managers for related object access
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
By default, Django uses a "bare" (i.e. default) manager when accessing related
|
By default, Django uses an instance of a "plain" manager class when accessing
|
||||||
objects (i.e. ``choice.poll``). If this default isn't appropriate for your
|
related objects (i.e. ``choice.poll``), not the default manager on the related
|
||||||
default manager, you can force Django to use a custom manager for related object
|
object. This is because Django needs to be able to retrieve the related
|
||||||
attributes by giving it a ``use_for_related_fields`` property::
|
object, even if it would otherwise be filtered out (and hence be inaccessible)
|
||||||
|
by the default manager.
|
||||||
|
|
||||||
class MyManager(models.Manager)::
|
If the normal plain manager class (:class:`django.db.models.Manager`) is not
|
||||||
use_for_related_fields = True
|
appropriate for your circumstances, you can force Django to use the same class
|
||||||
...
|
as the default manager for your model by setting the `use_for_related_fields`
|
||||||
|
attribute on the manager class. This is documented fully below_.
|
||||||
|
|
||||||
|
.. _below: manager-types_
|
||||||
...
|
|
||||||
|
|
||||||
Custom managers and model inheritance
|
Custom managers and model inheritance
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
@ -221,3 +226,103 @@ 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.
|
||||||
|
|
||||||
|
.. _manager-types:
|
||||||
|
|
||||||
|
Controlling Automatic Manager Types
|
||||||
|
===================================
|
||||||
|
|
||||||
|
This document has already mentioned a couple of places where Django creates a
|
||||||
|
manager class for you: `default managers`_ and the "plain" manager used to
|
||||||
|
`access related objects`_. There are other places in the implementation of
|
||||||
|
Django where temporary plain managers are needed. Those automatically created
|
||||||
|
managers will normally be instances of the :class:`django.db.models.Manager`
|
||||||
|
class.
|
||||||
|
|
||||||
|
.. _default managers: manager-names_
|
||||||
|
.. _access related objects: managers-for-related-objects_
|
||||||
|
|
||||||
|
Throughout this section, we will use the term "automatic manager" to mean a
|
||||||
|
manager that Django creates for you -- either as a default manager on a model
|
||||||
|
with no managers, or to use temporarily when accessing related objects.
|
||||||
|
|
||||||
|
Sometimes this default class won't be the right choice. One example is in the
|
||||||
|
`django.contrib.gis` application that ships with Django itself. All `gis`
|
||||||
|
models must use a special manager class (``GeoManager``) because they need a
|
||||||
|
special queryset (``GeoQuerySet``) to be used for interacting with the
|
||||||
|
database. It turns out that models which require a special manager like this
|
||||||
|
need to use the same manager class wherever an automatic manager is created.
|
||||||
|
|
||||||
|
Django provides a way for custom manager developers to say that their manager
|
||||||
|
class should be used for automatic managers whenever it is the default manager
|
||||||
|
on a model. This is done by setting the ``use_for_related_fields`` attribute on
|
||||||
|
the manager class::
|
||||||
|
|
||||||
|
class MyManager(models.Manager):
|
||||||
|
use_for_related_fields = True
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
If this attribute is set on the *default* manager for a model (only the
|
||||||
|
default manager is considered in these situations), Django will use that class
|
||||||
|
whenever it needs to automatically create a manager for the class. Otherwise,
|
||||||
|
it will use :class:`django.db.models.Manager`.
|
||||||
|
|
||||||
|
.. admonition:: Historical Note
|
||||||
|
|
||||||
|
Given the purpose for which it's used, the name of this attribute
|
||||||
|
(``use_for_related_fields``) might seem a little odd. Originally, the
|
||||||
|
attribute only controlled the type of manager used for related field
|
||||||
|
access, which is where the name came from. As it became clear the concept
|
||||||
|
was more broadly useful, the name hasn't been changed. This is primarily
|
||||||
|
so that existing code will :ref:`continue to work <misc-api-stability>` in
|
||||||
|
future Django versions.
|
||||||
|
|
||||||
|
Writing Correct Managers For Use In Automatic Manager Instances
|
||||||
|
---------------------------------------------------------------
|
||||||
|
|
||||||
|
As already suggested by the `django.contrib.gis` example, above, the
|
||||||
|
``use_for_related_fields`` feature is primarily for managers that need to
|
||||||
|
return a custom ``QuerySet`` subclass. In providing this functionality in your
|
||||||
|
manager, there are a couple of things to be remember and that's the topic of
|
||||||
|
this section.
|
||||||
|
|
||||||
|
Do not filter away any results in this type of manager subclass
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
One reason an automatic manager is used is to access objects that are related
|
||||||
|
to from some other model. In those situations, Django has to be able to see
|
||||||
|
all the objects for the model it is fetching, so that *anything* which is
|
||||||
|
referred to can be retrieved.
|
||||||
|
|
||||||
|
If you override the ``get_query_set()`` method and filter out any rows, Django
|
||||||
|
will return incorrect results. Don't do that. A manager that filters results
|
||||||
|
in ``get_query_set()`` is not appropriate for use as an automatic manager.
|
||||||
|
|
||||||
|
Set ``use_for_related_fields`` when you define the class
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The ``use_for_related_fields`` attribute must be set on the manager *class*,
|
||||||
|
object not on an *instance* of the class. The earlier example shows the
|
||||||
|
correct way to set it, whereas the following will not work::
|
||||||
|
|
||||||
|
# BAD: Incorrect code
|
||||||
|
class MyManager(models.Manager):
|
||||||
|
...
|
||||||
|
|
||||||
|
# Sets the attribute on an instance of MyManager. Django will
|
||||||
|
# ignore this setting.
|
||||||
|
mgr = MyManager()
|
||||||
|
mgr.use_for_related_fields = True
|
||||||
|
|
||||||
|
class MyModel(models.Model):
|
||||||
|
...
|
||||||
|
objects = mgr
|
||||||
|
|
||||||
|
# End of incorrect code.
|
||||||
|
|
||||||
|
You also shouldn't change the attribute on the class object after it has been
|
||||||
|
used in a model, since the attribute's value is processed when the model class
|
||||||
|
is created and not subsequently reread. Set the attribute on the manager class
|
||||||
|
when it is first defined, as in the initial example of this section and
|
||||||
|
everything will work smoothly.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue