DDR爱好者之家 Design By 杰米

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的所有数据

补充知识:Django 中 Models 的 F()和 Q()函数

1、F() ---- 专门取对象中某列值的操作

F对象允许Django在未实际链接数据的情况下具有对数据库字段的值的引用。

通常情况下我们在更新数据时需要先从数据库里将原数据取出后方在内存里,然后编辑某些属性,最后提交。

all = BookInfo.objects.filter(auth="小明")
for b in all:
  price = b.price
  b.price = price + 10
  b.save
  
# 使用F对象来计算
BookInfo.objects.filter(auth="小明").update(price=F("price")+10)

2、Q() ---- 对对象的复杂查询

Q对象是Django对model查询中所使用的关键字参数进行封装后的一个对象。

Q对象可以通过 &(与)、 |(或)、 ~(非)运算来组合生成不同的Q对象,便于在查询操作中灵活地运用。

from django.db.models import Q
# 并且条件:与条件查询
models.User.objects.filter(条件1,条件2,条件n..)
models.User.objects.filter(Q(username='老王') & Q(userpass='admin'))

# 或者条件:或条件
models.User.objects.fliter(Q(username='老王') | Q(username='老李'))

# 取反条件
models.User.objects.filter(~Q(username='老王'))
models.User.objects.exclude(username='老王')

以上这篇Django中Q查询及Q()对象 F查询及F()对象用法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。

DDR爱好者之家 Design By 杰米
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
DDR爱好者之家 Design By 杰米

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。