Django Learning-Lecture Ten (Part I): QuerySet API Learning

1. QuerySet API

When we usually do query operations, we use the model name .objects. In fact, the model name .objects is a django.db.models.manager.Manager object, and the Manager class is an "empty shell" class, which does not have any properties and methods. All his methods are dynamically added by Python, copied from the QuerySet classimage

So if we want to learn the search operation of the ORM model, we must first learn how to use some APIs on the QuerySet.

2. QuerySet method

When using the QuerySet for search operations, a variety of operations can be provided. For example, after filtering, we need to sort according to a certain field, then this series of operations can be carried out in a very smooth chain call. For example, if you want to get the title of 123 from the article table and sort the results according to the time of publication after extraction, you can use the following method to complete

articles = Article.objects.filter(title='123').order_by('create_time')

You can see that the order_by method is called directly after the filter is executed. This shows that the object returned by the filter is an object with an order_by method. And this object is a new QuerySet object. So you can use the order_by method.

Then the following will introduce the methods that will return a new QuerySet object.
  • 1 filter.: Extract the data that meets the conditions and return a new QuerySet
  • 2 exclude.: Exclude data that meets the conditions and return a new QuerySet

Extract those hellobooks whose title does not contain

Article.objects.exclude(title__contains='hello')

3 annotate.: Add a new field using query expressions (aggregate functions, F expressions, Q expressions, Func expressions, etc.) to each object in the QuerySet

将在每个对象中都添加一个`author__name`的字段,用来显示这个文章的作者的年龄
articles = Article.objects.annotate(author_name=F("author__name"))

4 order_by.: Specify to sort the query results according to a certain field. If you want to sort by flashback, you can add a minus sign in front of this field

 # 根据创建的时间正序排序(从小到大,默认排序规则)
 articles = Article.objects.order_by("create_time")

 # 根据创建的时间倒序排序
 articles = Article.objects.order_by("-create_time")

 # 根据作者的名字进行排序
 articles = Article.objects.order_by("author__name")

 # 首先根据创建的时间进行排序,如果时间相同,则根据作者的名字进行排序
 articles = Article.objects.order_by("create_time",'author__name')

 # 根据图书订单的评分来排序
articles = BookOrder.objects.order_by("book__rating")

5 values.: Used to specify which fields need to be extracted when extracting data. By default, all the fields in the table will be extracted. You can use values ​​to specify, and after using the values ​​method, the data type in the extracted QuerySet is not the model, but the fields and fields specified in the values ​​method. Dictionary of values

articles = Article.objects.values("title",'content')
for article in articles:
     print(article)
以上打印出来的article是类似于{"title":"abc","content":"xxx"}的形式

6 values_list.: Similar to values. Only in the returned QuerySet, it is not a dictionary, but a tuple

articles = Article.objects.values_list("id","title")
print(articles)

Then after printing the articles, the result is <QuerySet [(1,'abc'),(2,'xxx'),...]> etc.

7 all.: Get the QuerySet object of this ORM model.

  1. select_related: While extracting the data of a certain model, the related data is also extracted in advance.
    For example, to extract article data, you can use select_relatedto authorextract the information. When you use article.author again in the future, you don't need to visit the database again. Can reduce the number of database queries
article = Article.objects.get(pk=1)
>> article.author # 重新执行一次查询语句
article = Article.objects.select_related("author").get(pk=2)
>> article.author # 不需要重新执行查询语句了

selected_relatedCan only be used in 一对多or 一对一, not in many-to-many or many-to-one. For example, the author of the article can be obtained in advance, but the article of this author cannot be obtained through the author, or all the tags of this article can be obtained through an article

9 prefetch_related.: This method is very similar to select_related, which is to reduce the number of queries when accessing data in multiple tables. This method is to solve 多对一and 多对多inquiries of the relationship. For example, to get the article with the hello string in the title and all his tags

from django.db import connection
articles = Article.objects.prefetch_related("tag_set").filter(title__contains='hello')
print(articles.query) # 通过这条命令查看在底层的SQL语句
for article in articles:
     print("title:",article.title)
     print(article.tag_set.all())

10 create.: Create a piece of data and save it in the database. This method is equivalent to creating an object with the specified model first, and then calling the save method of this object

article = Article(title='abc')
article.save()
# 下面这行代码相当于以上两行代码 
article = Article.objects.create(title='abc')

11. get_or_create:Search according to a certain condition, if found, then return this data, if not found, then create one

obj,created= Category.objects.get_or_create(title='默认分类')

If there is a category with a title equal to the default category, it will be found, if not, it will be created and stored in the database.
The return value of this method is a tuple, the first parameter obj of the tuple is the object, and the second parameter created represents whether it was created.

12 exists.: Judge whether the data of a certain condition exists. If you want to judge whether an element of a certain condition exists, it is recommended to use it exists, which is much more effective than using countor judging directly QuerySet.

if Article.objects.filter(title__contains='hello').exists():
    print(True)
比使用count更高效:
if Article.objects.filter(title__contains='hello').count() > 0:
    print(True)
也比直接判断QuerySet更高效:
if Article.objects.filter(title__contains='hello'):
    print(True)

13. update:Perform update operation, update command is also taken at the bottom of SQL. For example, to update the article field of all articles whose category is empty to the default category

Article.objects.filter(category__isnull=True).update(category_id=3)

Note that this method follows the updated logic. So after the update is completed, save to the database will not execute the save method, so the field set by auto_now will not be updated

14. Slice operation: Sometimes we look for data, it may only need a part of it

books = Book.objects.all()[1:3]
for book in books:
    print(book)

The slicing operation does not extract all the data from the database and then do the slicing operation. Instead, use LIMIE and OFFSET at the database level to help us complete it. So if you only need to fetch part of the data, it is recommended that you use the slice operation.

3. Convert the QuerySet to SQL to execute

Generate a QuerySet object and will not immediately be converted into SQL statements for execution

from django.db import connection
books = Book.objects.all()
print(connection.queries)

We can see that when printing connection.quries, an empty list is printed. It shows that the above QuerySet is not actually executed.

In the following cases QuerySet will be converted to SQL statement execution
  • 1. Iteration: When traversing the QuerySet object, the SQL statement will be executed first, and then the result will be returned for iteration. For example, the following code will be converted into a SQL statement:
for book in Book.objects.all():
    print(book)
    1. Use step size to do slice operation: QuerySet can do slice operation like a list. The slicing operation itself will not execute the SQL statement, but if the step size is provided when doing the slicing operation, the SQL statement will be executed immediately. It should be noted that the filter method cannot be executed after slicing, otherwise an error will be reported.
    1. Call the len function: call the len function to get the total number of data in the QuerySet and execute the SQL statement.
    1. Calling the list function: Calling the list function to convert a QuerySet object into a list object will execute SQL statements immediately.
    1. Judgment: If you judge a QuerySet, the SQL statement will be executed immediately.

Guess you like

Origin blog.csdn.net/scyllake/article/details/109060584