官术网_书友最值得收藏!

Solution details

QuerySet is an extremely powerful abstraction. They are lazily evaluated only when needed. Hence, building longer QuerySet by method-chaining (a form of fluent interface) does not affect the performance.

In fact, as more filtering is applied, the result dataset shrinks. This usually reduces the memory consumption of the result.

A model manager is a convenient interface for a model to get its QuerySet object. In other words, they help you use Django's ORM to access the underlying database. In fact, managers are implemented as very thin wrappers around a QuerySet object. Notice the identical interface:

    >>> Post.objects.filter(posted_by__username="a")
    [<Post: a: Hello World>, <Post: a: This is Private!>]
    
    >>> Post.objects.get_queryset().filter(posted_by__username="a")
    [<Post: a: Hello World>, <Post: a: This is Private!>]

The default manager created by Django, objects, has several methods, such as all, filter, or exclude that return a QuerySet. However, they only form a low-level API to your database.

Custom managers are used to create a domain-specific, higher-level API. This is not only more readable, but less affected by implementation details. Thus, you are able to work at a higher level of abstraction closely modeled to your domain.

Our previous example for public posts can be easily converted into a custom manager as follows:

# managers.py 
from django.db.models.query import QuerySet 
 
class PostQuerySet(QuerySet): 
    def public_posts(self): 
        return self.filter(privacy="public") 
 
PostManager = PostQuerySet.as_manager 

This convenient shortcut for creating a custom manager from a QuerySet object appeared in Django 1.7. Unlike other previous approaches, this PostManager object is chainable like the default objects manager.

It sometimes makes sense to replace the default objects manager with our custom manager, as shown in the following code:

from .managers import PostManager 
class Post(Postable): 
    ... 
    objects = PostManager() 

By doing this, to access public_posts our code gets considerably simplified to the following:

public = Post.objects.public_posts() 

Since the returned value is a QuerySet, they can be further filtered:

public_apology = Post.objects.public_posts().filter( 
                  message_startswith="Sorry") 

QuerySet have several interesting properties. In the next few sections, we can take a look at some common patterns that involve combining QuerySets.

主站蜘蛛池模板: 莱芜市| 通化市| 乐山市| 小金县| 江城| 大田县| 鹤山市| 湖南省| 正宁县| 台山市| 绥中县| 东乡县| 福安市| 颍上县| 福泉市| 庐江县| 永清县| 海淀区| 盐津县| 司法| 栾川县| 普兰店市| 棋牌| 招远市| 托克逊县| 武夷山市| 岳普湖县| 鸡西市| 凭祥市| 宁夏| 县级市| 客服| 珠海市| 西城区| 舟山市| 天台县| 宜春市| 绥化市| 桐庐县| 怀宁县| 唐河县|