<commit_before>.. _topics-db-managers:

========
Managers
========

.. currentmodule:: django.db.models

.. class:: Manager()

A ``Manager`` is the interface through which database query operations are
provided to Django models. At least one ``Manager`` exists for every model in
a Django application.

The way ``Manager`` classes work is documented in :ref:`topics-db-queries`;
this document specifically touches on model options that customize ``Manager``
behavior.

.. _manager-names:

Manager names
=============

By default, Django adds a ``Manager`` with the name ``objects`` to every Django
model class. However, if you want to use ``objects`` as a field name, or if you
want to use a name other than ``objects`` for the ``Manager``, you can rename
it on a per-model basis. To rename the ``Manager`` for a given class, define a
class attribute of type ``models.Manager()`` on that model. For example::

    from django.db import models

    class Person(models.Model):
        #...
        people = models.Manager()

Using this example model, ``Person.objects`` will generate an
``AttributeError`` exception, but ``Person.people.all()`` will provide a list
of all ``Person`` objects.

.. _custom-managers:

Custom Managers
===============

You can use a custom ``Manager`` in a particular model by extending the base
``Manager`` class and instantiating your custom ``Manager`` in your model.

There are two reasons you might want to customize a ``Manager``: to add extra
``Manager`` methods, and/or to modify the initial ``QuerySet`` the ``Manager``
returns.

Adding extra Manager methods
----------------------------

Adding extra ``Manager`` methods is the preferred way to add "table-level"
functionality to your models. (For "row-level" functionality -- i.e., functions
that act on a single instance of a model object -- use :ref:`Model methods
<model-methods>`, not custom ``Manager`` methods.)

A custom ``Manager`` method can return anything you want. It doesn't have to
return a ``QuerySet``.

For example, this custom ``Manager`` offers a method ``with_counts()``, which
returns a list of all ``OpinionPoll`` objects, each with an extra
``num_responses`` attribute that is the result of an aggregate query::

    class PollManager(models.Manager):
        def with_counts(self):
            from django.db import connection
            cursor = connection.cursor()
            cursor.execute("""
                SELECT p.id, p.question, p.poll_date, COUNT(*)
                FROM polls_opinionpoll p, polls_response r
                WHERE p.id = r.poll_id
                GROUP BY 1, 2, 3
                ORDER BY 3 DESC""")
            result_list = []
            for row in cursor.fetchall():
                p = self.model(id=row[0], question=row[1], poll_date=row[2])
                p.num_responses = row[3]
                result_list.append(p)
            return result_list

    class OpinionPoll(models.Model):
        question = models.CharField(max_length=200)
        poll_date = models.DateField()
        objects = PollManager()

    class Response(models.Model):
        poll = models.ForeignKey(Poll)
        person_name = models.CharField(max_length=50)
        response = models.TextField()

With this example, you'd use ``OpinionPoll.objects.with_counts()`` to return
that list of ``OpinionPoll`` objects with ``num_responses`` attributes.

Another thing to note about this example is that ``Manager`` methods can
access ``self.model`` to get the model class to which they're attached.

Modifying initial Manager QuerySets
-----------------------------------

A ``Manager``'s base ``QuerySet`` returns all objects in the system. For
example, using this model::

    class Book(models.Model):
        title = models.CharField(max_length=100)
        author = models.CharField(max_length=50)

...the statement ``Book.objects.all()`` will return all books in the database.

You can override a ``Manager``\'s base ``QuerySet`` by overriding the
``Manager.get_query_set()`` method. ``get_query_set()`` should return a
``QuerySet`` with the properties you require.

For example, the following model has *two* ``Manager``\s -- one that returns
all objects, and one that returns only the books by <NAME>::

    # First, define the Manager subclass.
    class DahlBookManager(models.Manager):
        def get_query_set(self):
            return super(DahlBookManager, self).get_query_set().filter(author='<NAME>')

    # Then hook it into the Book model explicitly.
    class Book(models.Model):
        title = models.CharField(max_length=100)
        author = models.CharField(max_length=50)

        objects = models.Manager() # The default manager.
        dahl_objects = DahlBookManager() # The Dahl-specific manager.

With this sample model, ``Book.objects.all()`` will return all books in the
database, but ``Book.dahl_objects.all()`` will only return the ones written by
<NAME>.

Of course, because ``get_query_set()`` returns a ``QuerySet`` object, you can
use ``filter()``, ``exclude()`` and all the other ``QuerySet`` methods on it.
So these statements are all legal::

    Book.dahl_objects.all()
    Book.dahl_objects.filter(title='Matilda')
    Book.dahl_objects.count()

This example also pointed out another interesting technique: using multiple
managers on the same model. You can attach as many ``Manager()`` instances to
a model as you'd like. This is an easy way to define common "filters" for your
models.

For example::

    class MaleManager(models.Manager):
        def get_query_set(self):
            return super(MaleManager, self).get_query_set().filter(sex='M')

    class FemaleManager(models.Manager):
        def get_query_set(self):
            return super(FemaleManager, self).get_query_set().filter(sex='F')

    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
        sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female')))
        people = models.Manager()
        men = MaleManager()
        women = FemaleManager()

This example allows you to request ``Person.men.all()``, ``Person.women.all()``,
and ``Person.people.all()``, yielding predictable results.

If you use custom ``Manager`` objects, take note that the first
``Manager`` Django encounters (in the order in which they're defined
in the model) has a special status. Django interprets this first
``Manager`` defined in a class as the "default" ``Manager``, and
several parts of Django (though not the admin application) will use
that ``Manager`` exclusively for that model. As a result, it's often a
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
an inability to retrieve objects you'd like to work with.

.. _managers-for-related-objects:

Using managers for related object access
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

By default, Django uses an instance of a "plain" manager class when accessing
related objects (i.e. ``choice.poll``), not the default manager on the related
object. This is because Django needs to be able to retrieve the related
object, even if it would otherwise be filtered out (and hence be inaccessible)
by the default manager.

If the normal plain manager class (:class:`django.db.models.Manager`) is not
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-inheritance:

Custom managers and model inheritance
-------------------------------------

Class inheritance and model managers aren't quite a perfect match for each
other. Managers are often specific to the classes they are defined on and
inheriting them in subclasses isn't necessarily a good idea. Also, because the
first manager declared is the *default manager*, it is important to allow that<commit_msg>Fixed #13035 - Incorrect documentation regarding admin and default managers<commit_after>.. _topics-db-managers:

========
Managers
========

.. currentmodule:: django.db.models

.. class:: Manager()

A ``Manager`` is the interface through which database query operations are
provided to Django models. At least one ``Manager`` exists for every model in
a Django application.

The way ``Manager`` classes work is documented in :ref:`topics-db-queries`;
this document specifically touches on model options that customize ``Manager``
behavior.

.. _manager-names:

Manager names
=============

By default, Django adds a ``Manager`` with the name ``objects`` to every Django
model class. However, if you want to use ``objects`` as a field name, or if you
want to use a name other than ``objects`` for the ``Manager``, you can rename
it on a per-model basis. To rename the ``Manager`` for a given class, define a
class attribute of type ``models.Manager()`` on that model. For example::

    from django.db import models

    class Person(models.Model):
        #...
        people = models.Manager()

Using this example model, ``Person.objects`` will generate an
``AttributeError`` exception, but ``Person.people.all()`` will provide a list
of all ``Person`` objects.

.. _custom-managers:

Custom Managers
===============

You can use a custom ``Manager`` in a particular model by extending the base
``Manager`` class and instantiating your custom ``Manager`` in your model.

There are two reasons you might want to customize a ``Manager``: to add extra
``Manager`` methods, and/or to modify the initial ``QuerySet`` the ``Manager``
returns.

Adding extra Manager methods
----------------------------

Adding extra ``Manager`` methods is the preferred way to add "table-level"
functionality to your models. (For "row-level" functionality -- i.e., functions
that act on a single instance of a model object -- use :ref:`Model methods
<model-methods>`, not custom ``Manager`` methods.)

A custom ``Manager`` method can return anything you want. It doesn't have to
return a ``QuerySet``.

For example, this custom ``Manager`` offers a method ``with_counts()``, which
returns a list of all ``OpinionPoll`` objects, each with an extra
``num_responses`` attribute that is the result of an aggregate query::

    class PollManager(models.Manager):
        def with_counts(self):
            from django.db import connection
            cursor = connection.cursor()
            cursor.execute("""
                SELECT p.id, p.question, p.poll_date, COUNT(*)
                FROM polls_opinionpoll p, polls_response r
                WHERE p.id = r.poll_id
                GROUP BY 1, 2, 3
                ORDER BY 3 DESC""")
            result_list = []
            for row in cursor.fetchall():
                p = self.model(id=row[0], question=row[1], poll_date=row[2])
                p.num_responses = row[3]
                result_list.append(p)
            return result_list

    class OpinionPoll(models.Model):
        question = models.CharField(max_length=200)
        poll_date = models.DateField()
        objects = PollManager()

    class Response(models.Model):
        poll = models.ForeignKey(Poll)
        person_name = models.CharField(max_length=50)
        response = models.TextField()

With this example, you'd use ``OpinionPoll.objects.with_counts()`` to return
that list of ``OpinionPoll`` objects with ``num_responses`` attributes.

Another thing to note about this example is that ``Manager`` methods can
access ``self.model`` to get the model class to which they're attached.

Modifying initial Manager QuerySets
-----------------------------------

A ``Manager``'s base ``QuerySet`` returns all objects in the system. For
example, using this model::

    class Book(models.Model):
        title = models.CharField(max_length=100)
        author = models.CharField(max_length=50)

...the statement ``Book.objects.all()`` will return all books in the database.

You can override a ``Manager``\'s base ``QuerySet`` by overriding the
``Manager.get_query_set()`` method. ``get_query_set()`` should return a
``QuerySet`` with the properties you require.

For example, the following model has *two* ``Manager``\s -- one that returns
all objects, and one that returns only the books by <NAME>::

    # First, define the Manager subclass.
    class DahlBookManager(models.Manager):
        def get_query_set(self):
            return super(DahlBookManager, self).get_query_set().filter(author='<NAME>')

    # Then hook it into the Book model explicitly.
    class Book(models.Model):
        title = models.CharField(max_length=100)
        author = models.CharField(max_length=50)

        objects = models.Manager() # The default manager.
        dahl_objects = DahlBookManager() # The Dahl-specific manager.

With this sample model, ``Book.objects.all()`` will return all books in the
database, but ``Book.dahl_objects.all()`` will only return the ones written by
<NAME>.

Of course, because ``get_query_set()`` returns a ``QuerySet`` object, you can
use ``filter()``, ``exclude()`` and all the other ``QuerySet`` methods on it.
So these statements are all legal::

    Book.dahl_objects.all()
    Book.dahl_objects.filter(title='Matilda')
    Book.dahl_objects.count()

This example also pointed out another interesting technique: using multiple
managers on the same model. You can attach as many ``Manager()`` instances to
a model as you'd like. This is an easy way to define common "filters" for your
models.

For example::

    class MaleManager(models.Manager):
        def get_query_set(self):
            return super(MaleManager, self).get_query_set().filter(sex='M')

    class FemaleManager(models.Manager):
        def get_query_set(self):
            return super(FemaleManager, self).get_query_set().filter(sex='F')

    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
        sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female')))
        people = models.Manager()
        men = MaleManager()
        women = FemaleManager()

This example allows you to request ``Person.men.all()``, ``Person.women.all()``,
and ``Person.people.all()``, yielding predictable results.

If you use custom ``Manager`` objects, take note that the first ``Manager``
Django encounters (in the order in which they're defined in the model) has a
special status. Django interprets the first ``Manager`` defined in a class as
the "default" ``Manager``, and several parts of Django will use that ``Manager``
exclusively for that model. As a result, it's a good idea to be careful in
your choice of default manager in order to avoid a situation where overriding
``get_query_set()`` results in an inability to retrieve objects you'd like to
work with.

.. _managers-for-related-objects:

Using managers for related object access
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

By default, Django uses an instance of a "plain" manager class when accessing
related objects (i.e. ``choice.poll``), not the default manager on the related
object. This is because Django needs to be able to retrieve the related
object, even if it would otherwise be filtered out (and hence be inaccessible)
by the default manager.

If the normal plain manager class (:class:`django.db.models.Manager`) is not
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-inheritance:

Custom managers and model inheritance
-------------------------------------

Class inheritance and model managers aren't quite a perfect match for each
other. Managers are often specific to the classes they are defined on and
inheriting them in subclasses isn't necessarily a good idea. Also, because the
first manager declared is the *default manager*, it is important to allow that
{'fraction_non_alphanumeric': 0.12101080342729417, 'fraction_numerical': 0.00378740841922265, 'mean_word_length': 3.5525720746184284, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5871129', 'n_tokens_mistral': 4395, 'n_tokens_neox': 4166, 'n_words': 1820}