Django Official Document--Manager (Database operation interface) __ Database

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

The manager is the database operation interface for the Django model. The model in each Django application has at least one manager.

The way the manager class works is described in detail in constructing queries. This article mainly talks about the custom manager. Manager Name ¶

By default, Django adds a manager named objects to 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's name in the underlying definition of the model. The method of renaming is to define a models in the model. Class property of the Manager () type. For example:

From django.db import Models

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

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

You can use the custom manager in the model and initialize the manager by extending the base manager class.

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

Adding additional manager methods is the preferred way to add "table-level" functionality to the model. (To increase the "row-level" feature that acts on a single instance of a model object, use the model method instead of the manager method.) )

The custom Manager method can return anything, not necessarily returning 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 that 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 "" "
            _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 example above, you can use OpinionPoll.objects.with_counts () to return a list of Opininpoll objects with num_responses properties.

Another note is that the manager method can be self.model to obtain the model classes it relies on. Modify 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.

Overloaded Manager.get_query_set () can overload the manager's underlying query set. Get_query_set () should return a set of queries that match your needs.

For example, the following model has two managers, one returns all objects, and the other returns only objects that are author 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 upper 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 () only returns the book Roald Dah1 by the author.

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 number of Manager () instances to a model. This is a convenient way to define a common "filter" for the 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 for you to use Person.men.all (), Person.women.all (), and Person.people.all () to obtain definitive results.

If you use a custom Manager object, be aware that the first manager (depending on the order in which the model is defined) has a special state. Django takes the first manager as the default manager, and the different parts of Django (including DumpData) use only the default ' manager ' of the model. So think carefully about how to define the first manager so that you don't get the right results in the query. associating objects with manager actions ¶

By default, Django uses an instance of the "Concise" manager class (such as Choice.poll) when manipulating the associated object, rather than the default manager for the associated object itself. Only in this way can Django get the associated object in any case (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 to set the model's Use_for_related_fields properties. See below for details. Custom Manager and model inheritance ¶

When inheriting a model class, it is sometimes inappropriate for the manager of the model to inherit at the same time. Because the manager is typically targeted at a particular class. Also because the first manager is considered as 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 typically for a specific non-abstract base class. If you want to reuse the manager in a non-abstract base class, you must explicitly redefine the manager in its subclass. The manager of an abstract base class is always inherited by its subclass. The name of the organizer uses Python's usual name handling (the name of the subclass overloads all other names; the name comes from the first parent class). Abstract base classes are common information and behavior for their subclasses, and all their managers are inherently used to handle common information and should be inherited. If the manager is declared in the model class, then the first declared manager is the default manager. If there is no declaration, and the class inherits from an abstract base class, the default manager for the first parent abstract base class in the inheritance relationship is the default manager for this class. If you do not explicitly declare any manager, you will use the general default manager of Django itself.

The rules above provide sufficient flexibility 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 the manager is not declared in a subclass, then the 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 above example, suppose you want to add an extra manager, but still use the manager of the parent class Abstractbase as the default manager. You cannot add a new manager directly to a subclass, because the newly added manager will overload the parent class's manager and become the default manager. You must first explicitly declare the manager of all the parent classes. 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 "Extra_manager" attribute.
Implementation Essentials ¶

Whether you add any functionality to the custom manager, the manager instance must be shallow to replicate. For example, the following code should be able to execute through:

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

When you execute some queries, Django performs a shallow copy, and those queries fail if your manager cannot be shallow copied.

If your manager cannot be copied, most of the cases will not be a problem. However, if you overload some proprietary methods of the __GETATTR__ or manager, then you should make sure that your manager can be copied in a shallow way. controlling the Auto manager type ¶

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

In this section, we use the automatic Manager to refer to the manager that Django created for you. The Auto Manager includes the default manager for models that do not define the manager and the manager that is used temporarily when the associated object is manipulated.

Sometimes using the default manager is not the right choice. For example, in Django Django.contrib.gis applications, all GIS models must use a Special Manager class (Geomanager) because the model requires a special set of queries (Geoqueryset) to interact with the database. That is, sometimes the model does not need to be created automatically 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 the setting works in the default manager), then Django will always use the manager, or it will use Django.db.models.Manager.

Historical origins

Depending on the purpose of the property, the name of the property (Use_for_related_fields) may appear trivial. Because it turns out, this property is used only to control the associated fields of the action manager. When the concept of this attribute is gradually defined, its name does not change. This is only a preliminary case, and the code will continue to improve in the later versions of Django. using the correct manager in the auto-organizer instance ¶

As we have suggested in the Django.contrib.gix example above, the Use_for_related_fields feature is primarily used for managers who need to return a custom query collection class. In order for the manager to work effectively, there is something to keep in mind: don't filter out any results in this sort of manager subclass ¶

One reason is that an automatic 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 other models obtained. So don't 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 it. A manager that filters the results of Get_query_set () is not suitable for an automatic manager. You should set the use_for_related_fields¶ when you define a class

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

 # Error: Incorrect code class Mymanager (models. Manager):. # Set properties in Mymanager instance.
Django ignores this setting. MGR = Mymanager () Mgr.use_for_related_fields = True class MyModel (models. Model): ... objects = Mgr # error code ended. </

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.