文章目录
Django Q/F
#1 环境
Python3.7.3
Django==2.0.6
#2 开始
#2.1 django F()表达式
每次获取times当前的值,再+1,这样需要将times值取出,存到内存中
obj = models.Test.objects.get(name="cox")
obj.times = obj.times + 1
obj.save()
虽然 obj.times = F(“times”) + 1
看起来像常规的Python为实例属性赋值,但实际上它是一个描述数据库上操作的SQL结构
当Django遇到要给F()实例,它会覆盖标准的Python运算符来创建一个封装的SQL表达式;在这个例子中,指示数据库增加由 obj.times 表示的数据库字段。
无论 obj.times 的值是或曾是什么,Python永远不需要知道–完全由数据库来处理。Python通过Django的F()类做的所有事情仅是参考某个字段创建SQL语法来描述操作。
obj = models.Test.objects.get(name="cox")
obj.times = F("times") + 1
obj.save()
因此,F()可以通过以下方式提供性能优势
- 直接在数据库中操作而不是python
- 减少一些操作所需的数据库查询次数
#2.2 F()操作在 obj.save() 后会持续存在
如果times的值是1,那么经过n次save()之后,times的值是2
obj = models.Test.objects.get(name="cox")
obj.times = obj.times + 1
obj.save()
obj.save()
obj.save()
如果times的值是1,那么经过n次save()之后,times的值是1+n,而不是2,就是因为F()操作在 obj.save() 后会持续存在
obj = models.Test.objects.get(name="cox")
obj.times = F("times") + 1
obj.save()
obj.save()
obj.save()
#2.3 F()再过滤(filter)中的使用
获取表中收入(input_price)大于支出(output_price)的数据
models.Test.objects.filter(input_price__gt=F("output_price"))
Django支持F()对象使用加、减、乘、除、取模和幂运算等算术操作,两个操作数可以是常数或F()对象
models.Test.objects.filter(input_price__gt=F("output_price")*2)
models.Test.objects.filter(input_price__gt=F("output_price")+F("output_price"))
你还可以在F()对象中使用双下划线标记来跨越关联关系。 带有双下划线的F()对象将引入任何需要的join 操作以访问关联的对象
models.Test.objects.filter(authors__name=F('blog__name'))
对于date 和date/time 字段,你可以给它们加上或减去一个timedelta对象
from datetime import timedelta
models.Test.objects.filter(mod_date__gt=F('pub_date') + timedelta(days=3))
#2.4 Django Q()表达式
当我们在查询的条件中需要组合条件时(例如两个条件“且”或者“或”)时。我们可以使用Q()查询对象
from django.db.models import Q
models.Author.objects.filter(Q(name="cox") | Q(name="Tom")) # 获取在Author表中,name等于cox和name等于cox的所有数据
models.Author.objects.filter(Q(name="cox") & Q(age=12))# 获取在Author表中,name等于cox并且age等于12的所有数据
#2.5 Q()传入条件查询
q1 = Q()
q1.connector = 'OR'
q1.children.append(('name', "cox"))
q1.children.append(('name', "Tom"))
q1.children.append(('name', "Jeck"))
models.Author.objects.filter(q1) # 在Author表中,name等于cox/Tom/Jeck的所有数据
con = Q()
q1 = Q()
q1.connector = 'OR'
q1.children.append(('name', "cox"))
q1.children.append(('name', "Tom"))
q1.children.append(('name', "Jeck"))
q2 = Q()
q2.connector = 'OR'
q2.children.append(('age', 12))
con.add(q1, 'AND')
con.add(q2, 'AND')
models.Author.objects.filter(con) # 在Author表中,name等于cox/Tom/Jeck的 并且 满足age等于12 的所有数据
#2.6 Q()非
在Q()语句中,~代表非
models.Author.objects.filter(~Q(name="cox")) # 获取在Author表中,name不等于cox的所有数据