Django Official documentation--Manager (Database operations interface) __ Database

Source: Internet
Author: User
Tags abstract class manager documentation error code inheritance shallow copy
Manager ¶Class Manager¶

Manager is the database operation interface of the Django model. The model in each Django app has at least one manager.

The way the manager class works is described in detail in constructing the query. This article focuses on customizing the manager. Manager Name ¶

By default, Django adds a manager named objects for each model class. But if you want to use objects as a field name or you don't want to use objects as the name of the manager, you can rename the manager name in the model's underlying definition. The method of renaming is to define a models in the model. The class property of the Manager () type. For example:

From django.db import Models

class person (models. Model):
    # ...
    People = models. Manager ()

In the above example, if you use Person.objects, a Attributeerror exception is thrown, but using Person.people.all () returns a list of all the person objects. Custom Manager ¶

By extending the Base manager class, you can use the custom manager in the model and initialize the manager.

We want to use the custom manager for two purposes: Add an additional manager method and/or modify the original query set returned by the manager. Add an additional manager method ¶

Adding an additional manager approach is the preferred way to add table-level functionality to the model. (To increase the line-level functionality of a single instance in a model object, use the model method instead of the manager method.) )

The custom Manager method can return anything, not necessarily to return a query set.

For example, the following custom Manager provides a with_counts () method that returns a list of all opinionpoll, each of which has a num_responses property, which represents an aggregate number:

 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 (model S.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 () 

Using the model in the previous example, you can use OpinionPoll.objects.with_counts () to return a list of Opininpoll objects with the Num_responses property.

Another note is that the manager method can be self.model to get the model class it is attached to. modifying the original manager query set ¶

A manager's underlying query set returns all objects in the system. For example, use this model:

Class book (Models. Model):
    title = models. Charfield (max_length=100)
    author = models. Charfield (MAX_LENGTH=50)

... The statement Book.objects.all () returns all the books in the database.

You can overload the manager's underlying query set by overloading Manager.get_query_set (). Get_query_set () should return a query set that meets your needs.

For example, the following model has two managers, one returns all objects, and the other returns only the objects that the author is Roald DAH1:

# first define the subclass of the manager.
class Dahlbookmanager (models. Manager):
    def get_query_set (self):
        return Super (Dahlbookmanager, self). Get_query_set (). Filter (author= ' Roald Dahl ')

# explicitly installs the above subclass into the book model.
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.

In the example above, Book.objects.all () returns all the books in the database, but Book.dahl_objects.all () returns only the books that the author Roald Dah1.

Of course, because Get_query_set () returns a query set object, you can use filter (), exclude (), and all other query set methods on this object. The following statements are valid:

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

This example also shows an interesting trick: using multiple managers in the same model. You can attach any multi-Manager () instance to a model. This is a convenient way to define a common "filter" for a model.

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 makes it easy to use Person.men.all (), Person.women.all (), and Person.people.all () to get clear results.

If you use Custom Manager objects, be aware that the first manager (based on the order defined in the model) has a special state. Django uses the first manager as the default manager, and the different parts of Django (including DumpData) use only the default ' manager ' of the model. So be careful how you define the first manager so that you don't get the right results in the query. associating objects using manager actions ¶

By default, when you manipulate an object, Django uses an instance of a "concise" manager class (such as Choice.poll) instead of the default manager of the associated object itself. Only in this way can Django get associated objects under any circumstances (the default manager may be filtered out by the filter and become unusable).

If the general concise manager Class (Django.db.models.Manager) does not fit your appetite, you can use your own by setting the Use_for_related_fields property of the model. See below. Custom Manager and model inheritance ¶

When inheriting from a model class, the manager of the model is also inherited at times that is not appropriate. Because the manager is usually for a particular class. Also because the first manager is considered the default manager, it is important that the manager inherit at the same time that it should be controllable. So Django handles the custom manager and model inheritance: Managers in non-abstract base classes are not inherited. Because this manager is usually for a specific non-abstract base class. If you want to reuse a manager in a non-abstract base class, you must explicitly redefine the manager in its subclasses. The manager of an abstract base class is always inherited by its subclasses. The name of the manager uses Python's usual name handling (the name of the subclass overloads all other names; the name is from the first parent class). The abstract base class is used for the general information and behavior of its subclasses, and all its managers are inherently used to handle generic information and should be inherited. If the manager is declared in a model class, then the first declared manager is the default manager. If there is no declaration and the class is inherited from an abstract base class, then the default manager of the first parent abstract base class in the inheritance relationship is the default manager for this class. If no manager is explicitly declared, then Django's own generic default manager is used.

The above rules provide sufficient elasticity when using multiple custom managers in multiple models. For example, suppose you have the following base class:

Class Abstractbase (models. Model):
    ...
    objects = Custommanager ()

    class Meta:
        abstract = True

If a manager is not declared in a subclass, then objects in the parent class becomes the default manager:

Class Childa (abstractbase):
    ...
    # The default manager for this class is Custommanager.

If you want to inherit abstractbase, but want to use a different default manager, you can declare your own default manager in a subclass:

Class Childb (abstractbase):
    ...
    # an explicitly defined default manager.
    Default_manager = Othermanager ()

In the example above, Default_manager is the default manager. The objects manager is still available, but not the default manager.

Finally, for the example above, suppose you want to add an additional manager, but still use the Abstractbase manager of the parent class as the default manager. You cannot add a new manager directly to a subclass because the newly added manager overloads the manager of the parent class and becomes the default manager. Then you must explicitly declare all of the parent class's managers first. No, you can put the manager you want to add in another base class, and then introduce another base class after the base class you want to inherit:

Class Extramanager (models. Model):
    Extra_manager = Othermanager ()

    class Meta:
        abstract = True

class CHILDC (Abstractbase, Extramanager): ...
    # The default manager is Custommanager, but Othermanager
    can also be used as a property of # "Extra_manager".
Implementation Highlights ¶

Whether you add any functionality to the custom manager, the manager instance must be shallow copied. For example, the following code should be executed by:

>>> Import Copy
>>> manager = Mymanager ()
>>> my_copy = copy.copy (manager)

When some queries are executed, Django performs a shallow copy, and if your manager cannot be shallow copied, those queries will fail.

If your manager cannot be shallow copied, in most cases there will be no problem. However, if you reload some private methods of __getattr__ or manager, then you should make sure that your manager can be shallow copied. controlling the automatic manager type ¶

This article has talked about many of the manager classes that Django has created for you: ' Default manager ' _ and ' concise ' manager for manipulating associated objects. But the Django operation also requires some other concise manager. These auto-created managers are instances of Django.db.models.Manager.

In this section we will use "Auto Manager" to refer to the manager that Django created for you. The automatic Manager includes the default manager for models that do not have a manager defined and the manager that is used temporarily when manipulating objects.

Sometimes using the default manager is not the right choice. For example, in a Django-django.contrib.gis application, all GIS models must use a Special Manager class (Geomanager) because the model requires a special query set (Geoqueryset) to interact with the database. That is, sometimes the model does not need to be automatically created by the manager, but only with a specific manager.

Django solves this problem by setting the manager Use_for_related_fields property:

Class Mymanager (models. Manager):
    use_for_related_fields = True

    ...

If this property is set in the default manager of a model (only if it is set in the default manager), then Django will always use the manager, otherwise Django.db.models.Manager will be used.

Historical origins

Depending on the purpose of the attribute, the name of the property (Use_for_related_fields) may seem trivial. Because it turns out, this property is used only to control the associated fields of the operations manager. When the concept of this attribute is gradually clarified, its name does not change. This is only a preliminary situation and the code will continue to improve in future versions of Django. using the correct manager in an Auto manager instance ¶

As we have suggested in the Django.contrib.gix example above, the Use_for_related_fields feature is primarily used for managers that need to return a custom query subset class. There are some things to keep in mind for the manager to work effectively: do not filter out any results in this manager subclass ¶

One reason is that an auto manager is an associated object that is used to manipulate other models. In this case, Django must be able to see the objects of all the other models obtained. So do not filter out anything you get.

If you overload the Get_query_set () method and filter out any rows of the database, Django returns incorrect results. So don't do that. A manager that filters the results of Get_query_set () is not suitable for an automatic manager. when defining a class, you should set use_for_related_fields¶

The Use_for_related_fields property must be set in the manager class, not in an instance of a class. A good example is given above, and here is an example of the error:

 # Error: Incorrect code class Mymanager (models. Manager): ... # sets a property in an instance of Mymanager.
Django ignores this setting. MGR = Mymanager () Mgr.use_for_related_fields = True class MyModel (models. Model): objects = Mgr # error code end. </

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.