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.Manager
an object, this class is a shell class, all the methods above are from his QuerySet
copy of the class above them there. So long as we have learned QuerySet
, this objects
will know how to use.
Manager
Source 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 Meta
the class definitions ordering
to specify the default sort order. Sample code is as follows:
class Meta:
db_table = 'book_order'
ordering = ['create_time','-price']
The can also annotate
be 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
values
The return value is also a QuerySet
target, but that QuetySet
are installed with is not a model, but rather a one dict
dictionary.
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 author
in the model name
field, 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_name
if the name is called author
'll get an error, because Book
on 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 values
a 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 values
the 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_list
specify 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 QuerySet
object that QuerySet
the object without any modifications (such as filtration, etc.)
select_related
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_related
to achieve.
prefetch_related
This method is similar to select_related
when 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_related
the following sample code:
books = Book.objects.prefetch_related("bookorder_set")
Note that: in use prefetch_related
to 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.Prefetch
to 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 QuerySet
installed 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 defer
the field, use this field in the future, will re-initiate a request, so be careful operation, only
also 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 exists
it than using count
either evaluate QuerySet
much 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 distinct
to help us achieve, sample code as follows:
books = Book.objects.filter(bookorder__price__gte=80).distinct()
Note that, if distinct
used before order_by
, because it order_by
will extract the order_by
specified field, so re-use distinct
will 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 update
commands. 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 save
the method, it will not update the auto_now
field settings.
delete
delete
: Delete all the data to meet the conditions. Delete data, pay attention to on_delete
handling 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:
迭代
: 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)
-
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. -
Call
len函数
: Call QuerySet in len function to retrieve the total number of pieces of data will execute SQL statements. -
Call
list函数
: Call list function is used to convert a QuerySet object to the object list will immediately execute SQL statements. -
判断
: If you judge a QuerySet, will immediately execute SQL statements.