F表达式
Django 使用 F() 对象来生成一个 SQL 表达式,在数据库层面描述所需的操作。
官方文档:https://docs.djangoproject.com/zh-hans/3.2/ref/models/expressions/#django.db.models.F
读取数据并在内存操作:
reporter = Reporters.objects.get(name='Tintin')
reporter.stories_filed += 1
reporter.save()
使用F表达式,使用引用的方式,通过数据库语句实现
from django.db.models import F
reporter = Reporters.objects.get(name='Tintin')
reporter.stories_filed = F('stories_filed') + 1
reporter.save()
优化update语句:
reporter = Reporters.objects.filter(name='Tintin')
reporter.update(stories_filed=F('stories_filed') + 1)
# 或
Reporter.objects.all().update(stories_filed=F('stories_filed') + 1)
保存后刷新
F() 赋值在 Model.save() 之后持续存在,n次save会产生n次效果,需要刷新数据
reporter = Reporters.objects.get(pk=reporter.pk)
reporter.refresh_from_db()
在聚合中使用F
company = Company.objects.annotate(
chairs_needed=F('num_employees') - F('num_chairs'))
使用F表达式的优势:
- 让数据库,而不是 Python 来完成工作
- 减少某些操作所需的查询次数
Q表达式
Django 使用 Q() 对象表示一个 SQL 条件,它可以用于数据库相关的操作。
官方文档:https://docs.djangoproject.com/zh-hans/3.2/topics/db/queries/#complex-lookups-with-q
在类似 filter() 中,查询使用的关键字参数是通过 “AND” 连接起来的。如果你要执行更复杂的查询(例如,由 OR 语句连接的查询),你可以使用 Q 对象。
示例代码
Poll.objects.get(
Q(question__startswith='Who'),
Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
)
相当于SQL:
SELECT * from polls WHERE question LIKE 'Who%'
AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')
通过 & 和 | 操作符和括号分组,组合任意复杂度的语句。当然, Q 对象也可通过 ~ 操作符反转,允许在组合查询中组合普通查询或反向 (NOT) 查询:
Poll.objects.get(
Q(question__startswith='Who') | ~Q(pub_date__year=2005)
)