General Operation
The official website look professional documents, make professional programmers!
Must know will be 13
<1> all (): Search Results <2> filter (** kwargs) : it contains the object to match the filter of <3> get (** kwargs) : returns the given match the filter It objects, and only one result is returned, if the object matching the filter will throw more than one or no errors. <4> exclude (** kwargs) : it contains the given object does not match the filter criteria of <5> values (* field) : Returns a ValueQuerySet-- a special QuerySet, running is not obtained after a series of model examples of the object, but may be a dictionary iterative sequence <6> values_list (* field) : it values () are very similar, it returns a tuple sequence, values returns a dictionary sequence <7> order_by (* field): order query results <8> reverse (): reverse order query results, note reverse () only with defined generally on the order QuerySet that call (ordering specified in the Meta model class or call order_by () method). <9> distinct (): eliminate duplicate records (if you query across multiple tables, may be obtained from the returned results in the calculation of QuerySet reproducible results can now use distinct (), note that only supported by fields go in PostgreSQL. weight). <10> COUNT (): <11> first (): returns the first record <12> last (): returns the last record <13> exists (): if QuerySet contains data, returns True, otherwise return False
Return QuerySet object methods
all()
filter()
exclude()
order_by()
reverse()
distinct()
Special QuerySet
values () Returns an iterative sequence dictionaries
values_list () returns an ancestral sequence of iterations
Return specific object
get()
first()
last()
Returns a Boolean value methods are:
exists()
Returns the methods
count()
Single-table queries of magical double underline
(id__lt = 10, id__gt = 1 ) models.Tb1.objects.filter # acquires id value greater than 1 and less than 10 models.Tb1.objects.filter (id__in = [11, 22 , 33]) # acquires id equal to 11, 22,33 data models.Tb1.objects.exclude (id__in = [. 11, 22 is, 33 is]) # Not in models.Tb1.objects.filter (name__contains = "ven") # Get name field contains "ven" of models .Tb1.objects.filter (name__icontains = "ven") # icontains case insensitive models.Tb1.objects.filter (id__range = [1, 3 ]) # id ranges from 1 to 3, equivalent to the SQL bettwen and there are similar: startsWith, istartswith, endsWith, iendswith DATE field also be: models.Class.objects.filter (first_day__year = 2017)
ForeignKey operation
Forward Lookup
Object lookup (cross table)
grammar:
Objects . Associated field . Field
Example:
book_obj = models.Book.objects.first () # the first book of the object print (book_obj.publisher) # get this book publishers association objects print (book_obj.publisher.name) # get the name of the object Press
Lookup field (cross table)
grammar:
Associated field __ field
Example:
print(models.Book.objects.values_list("publisher__name"))
Reverse operation
Find objects
grammar:
obj. _set table
Example:
publisher_obj = models.Publisher.objects.first () # object is to find the first publishing house books = publisher_obj.book_set.all () # find the first book published by all titles = books.values_list ( "title") # find all the books of the first title published by a publishing house
Fields Find
grammar:
Table Name field __
Example:
titles = models.Publisher.objects.values_list("book__title")
ManyToManyField
class RelatedManager
"Association Manager" is used in many or many-associated context's manager.
It exists in the following two cases:
- Reverse Lookup foreign key relationships
- To-many relationship
It is simply a later point when there may be multiple objects can use the following method.
method
create()
Create a new object, saving the object, and add it to the associated object set in, returns the newly created object.
>>> import datetime >>> models.Author.objects.first().book_set.create(title="番茄物语", publish_date=datetime.date.today())
add()
Add the specified model object to the associated object set.
Add an object
>>> author_objs = models.Author.objects.filter(id__lt=3) >>> models.Book.objects.first().authors.add(*author_objs)
Adding id
>>> models.Book.objects.first().authors.add(*[1, 2])
set()
Updates the associated object model objects.
>>> book_obj = models.Book.objects.first() >>> book_obj.authors.set([2, 3])
remove()
Centralized model objects removed from the execution of the associated object
>>> book_obj = models.Book.objects.first() >>> book_obj.authors.remove(3)
clear()
Removes all objects from the related object.
>>> book_obj = models.Book.objects.first() >>> book_obj.authors.clear()
note:
For ForeignKey objects, clear () and remove () method is only present when the null = True.
for example:
ForeignKey field is not set to null = True,
class Book(models.Model): title = models.CharField(max_length=32) publisher = models.ForeignKey(to=Publisher)
No clear () and remove () method:
>>> models.Publisher.objects.first().book_set.clear() Traceback (most recent call last): File "<input>", line 1, in <module> AttributeError: 'RelatedManager' object has no attribute 'clear'
When the field is set ForeignKey null = True,
class Book(models.Model): name = models.CharField(max_length=32) publisher = models.ForeignKey(to=Class, null=True)
At this point there are clear () and remove () method:
>>> models.Publisher.objects.first().book_set.clear()
note:
- For all types of related fields, add (), create (), remove () and clear (), set () will immediately update the database. In other words, at any end of the association, it does not need to call the save () method.
Aggregate query and query packet
polymerization
aggregate () is QuerySet a termination clause, which means that it returns a dictionary that contains a number of key-value pairs.
The aggregate value is the name of the key identifier value is computed aggregate values. Name of the key is automatically generated out according to the name field and aggregate functions.
Used built-in functions:
from django.db.models import Avg, Sum, Max, Min, Count
Example:
>>> from django.db.models import Avg, Sum, Max, Min, Count
>>> models.Book.objects.all().aggregate(Avg("price")) {'price__avg': 13.233333}
If you want to specify a name for the aggregate values, it can provide to the aggregation clause.
>>> models.Book.objects.aggregate(average_price=Avg('price')) {'average_price': 13.233333}
If you want to generate more than one aggregate, you may provide Aggregate () clause add another parameter. So, if you want to know all the books of the maximum and minimum prices, it can be a query:
>>> models.Book.objects.all().aggregate(Avg("price"), Max("price"), Min("price")) {'price__avg': 13.233333, 'price__max': Decimal('19.90'), 'price__min': Decimal('9.90')}
Packet
We are here to brush up on grouping SQL statements.
Suppose now that there is a company employee table:
We use native SQL statements, in accordance with the requirements of the packet average wage:
select dept,AVG(salary) from employee group by dept;
ORM query:
from django.db.models import Avg Employee.objects.values("dept").annotate(avg=Avg("salary").values(dept, "avg")
Even table query packet:
SQL query:
select dept.name,AVG(salary) from employee inner join dept on (employee.dept_id=dept.id) group by dept_id;
ORM query:
from django.db.models import Avg models.Dept.objects.annotate(avg=Avg("employee__salary")).values("name", "avg")
More examples:
示例1:统计每一本书的作者个数
>>> book_list = models.Book.objects.all().annotate(author_num=Count("author")) >>> for obj in book_list: ... print(obj.author_num) ... 2 1 1
示例2:统计出每个出版社买的最便宜的书的价格
>>> publisher_list = models.Publisher.objects.annotate(min_price=Min("book__price")) >>> for obj in publisher_list: ... print(obj.min_price) ... 9.90 19.90
方法二:
>>> models.Book.objects.values("publisher__name").annotate(min_price=Min("price")) <QuerySet [{'publisher__name': '沙河出版社', 'min_price': Decimal('9.90')}, {'publisher__name': '人民出版社', 'min_price': Decimal('19.90')}]>
示例3:统计不止一个作者的图书
>>> models.Book.objects.annotate(author_num=Count("author")).filter(author_num__gt=1) <QuerySet [<Book: 番茄物语>]>
示例4:根据一本图书作者数量的多少对查询集 QuerySet进行排序
>>> models.Book.objects.annotate(author_num=Count("author")).order_by("author_num") <QuerySet [<Book: 香蕉物语>, <Book: 橘子物语>, <Book: 番茄物语>]>
示例5:查询各个作者出的书的总价格
>>> models.Author.objects.annotate(sum_price=Sum("book__price")).values("name", "sum_price") <QuerySet [{'name': '小精灵', 'sum_price': Decimal('9.90')}, {'name': '小仙女', 'sum_price': Decimal('29.80')}, {'name': '小魔女', 'sum_price': Decimal('9.90')}]>
F查询和Q查询
F查询
在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较。如果我们要对两个字段的值做比较,那该怎么做呢?
Django 提供 F() 来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。
示例1:
查询评论数大于收藏数的书籍
from django.db.models import F models.Book.objects.filter(commnet_num__gt=F('keep_num'))
Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。
models.Book.objects.filter(commnet_num__lt=F('keep_num')*2)
修改操作也可以使用F函数,比如将每一本书的价格提高30元
models.Book.objects.all().update(price=F("price")+30)
引申:
如果要修改char字段咋办?
如:把所有书名后面加上(第一版)
>>> from django.db.models.functions import Concat >>> from django.db.models import Value >>> models.Book.objects.all().update(title=Concat(F("title"), Value("("), Value("第一版"), Value(")")))
Q查询
filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 如果你需要执行更复杂的查询(例如OR语句),你可以使用Q对象。
示例1:
查询作者名是小仙女或小魔女的
models.Book.objects.filter(Q(authors__name="小仙女")|Q(authors__name="小魔女"))
你可以组合& 和| 操作符以及使用括号进行分组来编写任意复杂的Q 对象。同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询。
示例:查询作者名字是小仙女并且不是2018年出版的书的书名。
>>> models.Book.objects.filter(Q(author__name="小仙女") & ~Q(publish_date__year=2018)).values_list("title") <QuerySet [('番茄物语',)]>
查询函数可以混合使用Q 对象和关键字参数。所有提供给查询函数的参数(关键字参数或Q 对象)都将"AND”在一起。但是,如果出现Q 对象,它必须位于所有关键字参数的前面。
例如:查询出版年份是2017或2018,书名中带物语的所有书。
>>> models.Book.objects.filter(Q(publish_date__year=2018) | Q(publish_date__year=2017), title__icontains="物语") <QuerySet [<Book: 番茄物语>, <Book: 香蕉物语>, <Book: 橘子物语>]>
锁和事务
锁
select_for_update(nowait=False, skip_locked=False)
返回一个锁住行直到事务结束的查询集,如果数据库支持,它将生成一个 SELECT ... FOR UPDATE 语句。
举个例子:
entries = Entry.objects.select_for_update().filter(author=request.user)
所有匹配的行将被锁定,直到事务结束。这意味着可以通过锁防止数据被其它事务修改。
一般情况下如果其他事务锁定了相关行,那么本查询将被阻塞,直到锁被释放。 如果这不想要使查询阻塞的话,使用select_for_update(nowait=True)。 如果其它事务持有冲突的锁, 那么查询将引发 DatabaseError 异常。你也可以使用select_for_update(skip_locked=True)忽略锁定的行。 nowait和skip_locked是互斥的,同时设置会导致ValueError。
目前,postgresql,oracle和mysql数据库后端支持select_for_update()。 但是,MySQL不支持nowait和skip_locked参数。
使用不支持这些选项的数据库后端(如MySQL)将nowait=True或skip_locked=True转换为select_for_update()将导致抛出DatabaseError异常,这可以防止代码意外终止。
事务
import os if __name__ == '__main__': os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BMS.settings") import django django.setup() import datetime from app01 import models try: from django.db import transaction with transaction.atomic(): new_publisher = models.Publisher.objects.create(name="火星出版社") models.Book.objects.create(title="橘子物语", publish_date=datetime.date.today(), publisher_id=10) # 指定一个不存在的出版社id except Exception as e: print(str(e))