如何在Django模型中新增基于其他字段计算的字段?
解决方案
方法1:动态计算属性(不存储到数据库)
如果不需要将kt_21持久化到数据库,只是在代码中获取该值,直接在模型中定义一个属性即可,这种方式最简单:
class Issue(models.Model): date = models.DateTimeField(auto_now_add=True) customer = models.ForeignKey(Customer, on_delete=models.CASCADE) product = models.ForeignKey(Product, on_delete=models.CASCADE) quantity = models.PositiveIntegerField() kt = models.IntegerField() rate = models.FloatField() @property def kt_21(self): # 注意:kt是整数,21是整数,使用/会得到浮点数,若需要整数可改用// return self.kt / 21 * self.quantity
使用方式:
issue = Issue.objects.first() print(issue.kt_21) # 直接访问属性即可
注意:这种方式的属性无法用于数据库查询(比如Issue.objects.filter(kt_21__gt=10)),因为它只在Python层面计算,不涉及数据库。
方法2:存储到数据库的计算字段
如果需要用kt_21做数据库查询、排序等操作,需要将其存储到数据库中,有两种实现方式:
方式A:重写save方法手动计算
每次保存实例时自动计算并赋值:
class Issue(models.Model): date = models.DateTimeField(auto_now_add=True) customer = models.ForeignKey(Customer, on_delete=models.CASCADE) product = models.ForeignKey(Product, on_delete=models.CASCADE) quantity = models.PositiveIntegerField() kt = models.IntegerField() rate = models.FloatField() kt_21 = models.FloatField(null=True, blank=True) # 添加字段,允许空值方便迁移 def save(self, *args, **kwargs): # 保存前计算kt_21的值 self.kt_21 = self.kt / 21 * self.quantity super().save(*args, **kwargs)
注意:
- 先执行
makemigrations和migrate命令添加kt_21字段到数据库 - 对于已存在的旧数据,需要手动批量更新:
from django.db.models import F Issue.objects.update(kt_21=F('kt') / 21 * F('quantity'))
方式B:使用数据库原生生成字段(推荐,Django 3.2+)
如果使用PostgreSQL、MySQL 8.0+等支持生成字段的数据库,可以用Django的GeneratedField,让数据库自动维护该字段的值:
from django.db.models import GeneratedField, F class Issue(models.Model): date = models.DateTimeField(auto_now_add=True) customer = models.ForeignKey(Customer, on_delete=models.CASCADE) product = models.ForeignKey(Product, on_delete=models.CASCADE) quantity = models.PositiveIntegerField() kt = models.IntegerField() rate = models.FloatField() kt_21 = GeneratedField( expression=F('kt') / 21 * F('quantity'), output_field=models.FloatField(), db_persist=True, # 设为True则存储到数据库,False则是虚拟字段 )
这种方式不需要手动维护,数据库会在kt或quantity变化时自动更新kt_21的值,也支持用该字段做查询操作。
内容的提问来源于stack exchange,提问作者pip install logic
相关产品推荐
相关产品推荐

