使用 django.db.models.F 对象的 Django ORM 强大功能
在使用 Django 的过程中,常常会遇到 不想直接写 SQL 查询却需要执行复杂运算 的情况。此时,django.db.models.F 对象就显得非常有用。
本文将介绍 F 对象是什么、何时以及如何使用,并通过若干实战示例展示其强大之处。
1. F 对象是什么?
F 对象是 引用数据库字段值 的表达式。
也就是说,它不是模型实例,而是在 数据库层面 读取字段值,并可用于与其他字段比较或参与运算。
from django.db.models import F
核心要点 -
F对象不是 Python 对象,而会被转换为 SQL 表达式。 - 使用F可以让 数据库一次性完成运算,比在 Python 中先取值再计算更高效。
2. 为什么需要 F 对象?
2-1. 防止并发问题
想象一下下面的场景:
product.stock -= 1
product.save()
- 两个用户同时购买同一商品时,第一位用户会把
stock减 1 并保存,随后第二位用户读取到同样的值再次减 1。 - 结果导致
stock被减 2,出现错误。
使用 F 对象,数据库自身完成递减,从而避免并发冲突。
Product.objects.filter(id=product_id).update(stock=F('stock') - 1)
2-2. 复杂过滤
借助 F 对象,可以 与其他字段比较。
# 只查询 price 大于 discount_price 的商品
Product.objects.filter(price__gt=F('discount_price'))
2-3. 批量更新
F 对象可以让 一次查询 更新 多条记录。
# 所有商品价格上涨 10%
Product.objects.update(price=F('price') * 1.10)
3. F 对象的使用方法
3-1. 基本用法
from django.db.models import F
# 字段间比较
qs = Book.objects.filter(pages__gt=F('chapters'))
# 字段间运算
qs = Book.objects.update(pages=F('pages') + 10)
3-2. 与 Q 对象结合
使用 Q 对象可以构造 更复杂的条件。
from django.db.models import Q
qs = Book.objects.filter(
Q(pages__gt=F('chapters')) | Q(pages__lt=F('pages') * 2)
)
3-3. 与 annotate 结合
annotate 可以创建 虚拟字段 并加入查询集。
from django.db.models import F, Value, FloatField
qs = Book.objects.annotate(
ratio=F('pages') / F('chapters')
).filter(ratio__gt=5)
注意:
F对象的运算支持程度因数据库而异。例如,SQLite 可能不支持*运算,需要先行测试。
4. 实战示例
4-1. 库存管理
# 递减库存,若库存降至 0 则禁用
Product.objects.filter(id=product_id, stock__gt=0).update(
stock=F('stock') - 1,
is_active=Case(
When(stock=1, then=Value(False)),
default=Value(True),
output_field=BooleanField()
)
)
4-2. 折扣率计算
# 只查询折扣率 >= 20% 的商品
Product.objects.annotate(
discount_rate=F('discount_price') / F('price')
).filter(discount_rate__gte=0.2)
4-3. 批量价格上涨
# 将 electronics 类别下所有商品价格上涨 15%
Product.objects.filter(category='electronics').update(
price=F('price') * 1.15
)
5. 使用 F 对象的技巧
| 场景 | 推荐用法 |
|---|---|
| 并发 | update() + F |
| 字段比较 | filter(field__gt=F('other_field')) |
| 虚拟字段 | annotate(new_field=F('field1') + F('field2')) |
| 条件更新 | Case + When + F |
Tip:
F对象生成的查询会直接转为 SQL,建议通过 profiling 查看实际执行计划。
6. 结语
django.db.models.F 对象是 在数据库层面 进行运算的强大工具。 - 它能 解决并发问题, - 简化复杂过滤, - 以及 高效批量更新。
想进一步提升 Django ORM 的使用体验,建议多尝试 F 对象。

更多资料 - Django 官方文档: F expressions - 实战代码示例: GitHub Gist
Happy coding! 🚀
目前没有评论。