21.QuerySetAPI

 

QuerySet API:

We usually do the query time, are operated by the model name .objects way. In fact, the model name .objects is a django.db.models.manager.Manager object, Manager This class is a "shell" of the class, and he is not any properties and methods. His methods are all by way of Python dynamically added, copied from class QuerySet over.

Model .objects:

This object is django.db.models.manager.Manageran object, this class is a shell class, all the methods above are from his QuerySetcopy of the class above them there. So long as we have learned QuerySet, this objectswill know how to use.
ManagerSource Analysis:

class_name = "BaseManagerFromQuerySet"

class_dict = {
    '_queryset_class': QuerySet
}

class_dict.update(cls._get_queryset_methods(QuerySet))

# type动态的时候创建类
# 第一个参数是用来指定创建的类的名字。创建的类名是:BaseManagerFromQuerySet
# 第二个参数是用来指定这个类的父类。
# 第三个参数是用来指定这个类的一些属性和方法
return type(class_name,(cls,),class_dict)

_get_queryset_methods:这个方法就是将QuerySet中的一些方法拷贝出来

filter

The data is extracted to meet the conditions, returns a new QuerySet. Specific filter can provide what conditions inquiry

exclude

Exclude data conditions are met, and returns a new QuerySet. Sample code is as follows:

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


This code means that the title does not contain extracts of the book hello.

annotate

Each object to QuerySet are added using a query expression (aggregate function, F expression, Q expression, Func expression or the like) of the new field. Sample code is as follows:

articles = Article.objects.annotate(author_name=F("author__name"))


The above code will have to add a author__name field in each object, used to display the author of this article age.

aggregate

Aggregate functions.

order_by:

# 根据创建的时间正序排序
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')

Be sure to note is that, a plurality of order_by, will upset by preceding sorting rules, using the latter sort. For example, the following code:

articles = Article.objects.order_by("create_time").order_by("author__name")

He will be sorted according to the author's name, instead of using the time to create the article.
Of course, the model can also be defined in Metathe class definitions orderingto specify the default sort order. Sample code is as follows:

    class Meta:
        db_table = 'book_order'
        ordering = ['create_time','-price']

The can also annotatebe sorted defined fields. For example, to achieve sales of books sorted, then the sample code as follows:

books = Book.objects.annotate(order_nums=Count("bookorder")).order_by("-order_nums")
    for book in books:
        print('%s/%s'%(book.name,book.order_nums))

values

valuesThe return value is also a QuerySettarget, but that QuetySetare installed with is not a model, but rather a one dictdictionary.

If we want to extract a property of the object associated with this model, it is also possible, with the search order filter. The usage is the same as the sample code as follows:

books = Book.objects.values("id","name","author__name")


Above will be extracted authorin the model namefield, if we do not want the name, you want to change a name, you can use keyword parameters sample code as follows:

books = Book.objects.values("id","name",author_name=F("author__name"))


Custom name, not the model itself, and fields owned by the same, for example above author_nameif the name is called author'll get an error, because Bookon itself has a field called author.

In values, it is also possible to form a new field aggregate functions such as I would like to acquire the sales of each book, then the following sample code:

books = Book.objects.values("id","name",order_nums=Count("bookorder"))

If you call valuesa method, when any parameter is not passed, then the dictionary will acquire all the fields on the model and the corresponding value of the sample code is formed as follows:

books = Book.objects.values()

values_list

d with valuesthe same action but this method returns. QuerySet, the dictionary is not installed, but the tuples, the following sample code:

books = Book.objects.values_list("id","name")


Then returns the result of the code above is:

(1,"西游记")

If to values_listspecify only one field, then we can specify flat=True, such a result is not returned back in a tuple, but the value of this field, the following sample code:

books = Book.objects.values_list("name",flat=True)


The result returned is more than:

`三国演义`


Be sure to note that, flat can only be used in the case of only one field, otherwise it will error.

all methods

All data in the query model, a return QuerySetobject that QuerySetthe object without any modifications (such as filtration, etc.)

Find data in a table when a one-time data can be associated with other tables are extracted, so you can access the data tables associated with later time, do not find the database again, you can save some overhead. Example code show as below:

books = Book.objects.select_related("author","publisher")
for book in books:
    print(book.author.name)
    # 因为在提取book的时候,使用了select_related,那么以后在访问book.author的时候,不会再次向数据库重新发起查询


Note: this method can only be used outside the object associated with the key, for the kind-many, or many-to-achieve in the case where it can not be used, but should be used prefetch_relatedto achieve.

This method is similar to select_relatedwhen the method is used to query and extract data in advance to find out. However, this method is used to solve many to many, non-foreign key situation. This method will produce two queries, so If a foreign key query model is used select_related, if the query is a case where a non-many or a foreign key, use prefetch_relatedthe following sample code:

books = Book.objects.prefetch_related("bookorder_set")


Note that: in use prefetch_relatedto find out boororder_set, it is recommended not to carry out any operation, for example filter, or will produce more than N queries, affect the performance of queries such as the following code is wrong:

books = Book.objects.prefetch_related("bookorder_set")
for book in books:
    print(book.name)
    # 这个地方如果对bookorder_set进行了操作,那么就又会产生新的sql语句,前面的prefetch_related就相当于白做了
    oredrs = book.bookorder_set.fliter(price__gte=90)
    for order in orders:
        print(order.id)


So if you want to do is to find a set of pre-operation, then we can use django.db.models.Prefetchto complete, the sample code as follows:

# 先使用Prefetch把查找的条件写好,在放到prefetch_related中
from django.db.models import Prefetch
prefetch = Prefetch("bookorder_set",queryset=Bookorder.objects.filter(price__gte=90))
books = Book.objects.prefetch_related(prefetch)
for book in books:
    print(book.name)
    orders = book.bookorder_set.all()
    for order in orders:
        print(order.id)

defer和only

Both methods return a QuerySet, and this QuerySetinstalled with all models, rather than field
1 defer: This method is used to tell ORM, in a model query when filtering certain fields.
2 only: This method is used tell ONR, query a model, you can just extract certain fields.
Note: use deferthe field, use this field in the future, will re-initiate a request, so be careful operation, onlyalso empathy sample code as follows:

articles = list(Article.objects.defer("title"))
for article in articles:
    # 因为在上面提取的时候过滤了title
    # 这个地方重新获取title,将重新向数据库中进行一次查找操作
    print(article.title)
for sql in connection.queries:
    print('='*30)
    print(sql)

get

Meet the conditions of data acquisition, it returns the specific model. This function can only return one data, and if a number of conditions to the data, then this method throws MultipleObjectsReturned error, if given the absence of any data, it will be thrown DoesNotExit error. Therefore, this method can only get the data, and can only have only one.

create

Creating a data and saved to the database. This method is equivalent to first create an object with the specified model, and then call the save method of the object. Sample code is as follows:

article = Article(title='abc')
article.save()

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

bulk_create

Create multiple data, no matter how many pieces of data, a SQL statement to solve

get_or_create

If the given conditions data, it will come out to directly extract the data. If the data is not the given conditions, it will create data, and then return the data back.

count

count: Get the number of the extracted data. If you want to know the total number of pieces of data, it is recommended to use count, instead of using len(articles)this. Because count is used at the bottom select count(*)to achieve, which is much more efficient than using len function.

first和last

Returns QuerySet first and last data, the return value is the data model.

exisit

exists: Determine whether there is a condition of the data. To determine whether there is an element of the conditions, it is recommended to use existsit than using counteither evaluate QuerySetmuch more effective. Sample code is as follows:

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)

distinct

distinct: To get rid of those duplicate data. This method is used if the underlying database MySQL, it can not pass any parameters. For example, want to extract all of the sales price of more than 80 yuan of books and delete those duplicate, you can use distinctto help us achieve, sample code as follows:

books = Book.objects.filter(bookorder__price__gte=80).distinct()


Note that, if distinctused before order_by, because it order_bywill extract the order_byspecified field, so re-use distinctwill be based on the sole of multiple fields, so I will not repeat those data will be deleted. Sample code is as follows:

orders = BookOrder.objects.order_by("create_time").values("book_id").distinct()


So the above code because of the use order_by, even with a distinct, will be to repeat the book_id extracted.

update

Disposable can put all the data update completed
update: the update operation, the bottom is also taking in SQL updatecommands. For example, we want all category fields empty article article are updated to the default category. Sample code is as follows:

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


Note that this method is taking the update logic. Therefore saved to the database after the update does not perform savethe method, it will not update the auto_nowfield settings.

delete

delete: Delete all the data to meet the conditions. Delete data, pay attention to on_deletehandling specified.

Slicing

Slicing: Sometimes we find the data, there may be only part of it. So this time it can slice operation to help us complete. QuerySet slice operation just list a slice operation is the same. Sample code is as follows:

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


Slicing operation is not all the data extracted from the database to do the slicing operation. But the use of LIMIE and OFFSET at the database level to help us complete. So if you only need to take data when part of them, it is recommended that you use the slicing operation.

When Django QuerySet will be converted to SQL to perform:

Generate a QuerySet object does not immediately convert the SQL statement to execute.
For example, we get all the books under Book list:

books = Book.objects.all()
print(connection.queries)


We can see that at the time of printing connection.quries print is an empty list. Description above QuerySet does not really perform.
QuerySet will be converted in the following cases for the SQL statement:

  1. 迭代: When traversing QuerySet object, this will be the first to execute a SQL statement, and then the results returned to iterate. For example, the following code will be converted to SQL statement:
     for book in Book.objects.all():
         print(book)
    
  2. Use 步长to do 切片the operation: QuerySet can be sliced like a list of do the same operation. Do the slicing operation itself will not execute SQL statements, but if If a step is doing the slicing operation time, it will immediately execute SQL statements. It should be noted, can no longer perform the filter method to do after slicing, otherwise it will error.

  3. Call len函数: Call QuerySet in len function to retrieve the total number of pieces of data will execute SQL statements.

  4. Call list函数: Call list function is used to convert a QuerySet object to the object list will immediately execute SQL statements.

  5. 判断: If you judge a QuerySet, will immediately execute SQL statements.

Guess you like

Origin www.cnblogs.com/ys-python/p/11266224.html
21.