Django小技巧13: 使用F()表达式

翻译整理自: simpleisbetterthancomplex.com

在 Django QuerySets API 中, F() 用于直接在数据库中引用模型的值。假设你有一个带有price的 Product 模型, 你希望为所有的Product的价格上涨20%.

一个可以实现在解决方案:

Python

products = Product.objects.all()
for product in products:
    product.price *= 1.2
    product.save()

相反, 你可以在单个查询中更新price.

Python

from django.db.models import F

Product.objects.update(price=F('price') * 1.2)

你也可以对单个对象执行这个操作:

Python

product = Product.objects.get(pk=5009)
product.price = F('price') * 1.2
product.save()

要注意, 保存模型后, F()对象依然存在.

Python

product.price                   # price = Decimal('10.00')
product.price = F('price') + 1
product.save()                  # price = Decimal('11.00')
product.name = 'What the F()'
product.save()                  # price = Decimal('12.00')

所以, 在更新这样的字段后, product.price实际上保存的是django.db.models.expressions.CombinedExpression实例, 而不是实际结果。

如果要立即访问结果:

Python

product.price = F('price') + 1
product.save()
print(product.price)            # <CombinedExpression: F(price) + Value(1)>
product.refresh_from_db()
print(product.price)            # Decimal('13.00')

你可以使用F()实现annotate功能:

Python

from django.db.models import ExpressionWrapper, DecimalField

Product.objects.all().annotate(
    value_in_stock=ExpressionWrapper(
        F('price') * F('stock'), output_field=DecimalField()
    )
)

由于price是DecimalField, 而stock是IntegerField,我们需要将表达式包装在ExpressionWrapper中.

也可以用来过滤数据:

Python

Product.objects.filter(stock__gte=F('ordered'))

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏开发 & 算法杂谈

MultiRace-Efficient on-the-fly data race detection

     最近在研究数据竞争检测方法,之前的工作是参考了Eraser这个工具1997年提出的基于Lockset方法的动态数据检测,

902
来自专栏草根专栏

使用xUnit为.net core程序进行单元测试(1)

一. 导读 为什么要编写自动化测试程序(Automated Tests)? 可以频繁的进行测试 可以在任何时间进行测试,也可以按计划定时进行,例如:可以在半夜进...

3385
来自专栏智能大石头

STM32/GD32上内存堆栈溢出探测研究

无数次遭受堆栈溢出折磨,随着系统变得复杂,故障点越来越难以查找! 主要溢出情况如下: 1,一般RAM最后两块空间是堆Heap和栈Stack,堆从下往上用,栈从上...

2537
来自专栏肖蕾的博客

第十三章:图片资源打包器(TexturePacker)TexturePacker介绍TexturePacker 下载使用TextureAtlaspack文件格式

1.介绍:TexturePacker 是一款把若干张资源图片拼接为一张大图的工具。 2.特点: - 1.提高载入速度 把小图拼接成一张大图,一次载入,减少...

1624
来自专栏乐沙弥的世界

Linux/Unix shell sql 之间传递变量

       灵活结合Linux/Unix Shell 与SQL 之间的变量传输,极大程度的提高了DBA的工作效率,本文针对Linux/Unix shell s...

863
来自专栏杨建荣的学习笔记

两个关于权限设置的问题思考

最近这两天做动态菜单和权限校验,想到了两个有意思的问题。 第一个是对于一个用户的操作权限,无非就是这四个方面,增删改查。 如果通过字母来标识,可能就是增(I)删...

3517
来自专栏python3

python3--函数的有用信息,带参数的装饰器,多个装饰器装饰同一个函数

    我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改,所以我们必须允许代码扩展,添加新功能

3491
来自专栏张俊红

python数据分析笔记——数据加载与整理

Python数据分析——数据加载与整理 总第47篇 ▼ ? (本文框架) 数据加载 导入文本数据 ? 1、导入文本格式数据(CSV)的方法: 方法一:使用pd....

3818
来自专栏YG小书屋

ES-Spark连接ES后,ES Client节点流量打满分析

6233
来自专栏分布式系统进阶

Kafka消息的磁盘存储Kafka源码分析-汇总

可以看到使用FileMessageSet来操作Log文件, 使用OffsetIndex来操作Index文件

2382

扫码关注云+社区

领取腾讯云代金券