- Django Design Patterns and Best Practices
- Arun Ravindran
- 326字
- 2021-06-25 21:32:10
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.
- Python概率統(tǒng)計
- LabVIEW 2018 虛擬儀器程序設計
- Leap Motion Development Essentials
- Android Development with Kotlin
- C語言程序設計
- Hands-On JavaScript High Performance
- Getting Started with SQL Server 2012 Cube Development
- Learning ArcGIS for Desktop
- 零基礎趣學C語言
- 移動互聯(lián)網軟件開發(fā)實驗指導
- 持續(xù)集成與持續(xù)交付實戰(zhàn):用Jenkins、Travis CI和CircleCI構建和發(fā)布大規(guī)模高質量軟件
- Arduino計算機視覺編程
- Learning Android Application Testing
- Penetration Testing with the Bash shell
- STM8實戰(zhàn)