django - 根据其他列更新 django 模型列
问题描述
我有一个模型
class tbl_payment(models.Model):
document_id = models.ForeignKey(tbl_invoice, on_delete=models.CASCADE)
client_id = models.ForeignKey(tbl_customer, on_delete=models.CASCADE)
total_amount = models.DecimalField(max_digits=8, decimal_places=2, blank=True, null=True)
paid_amount = models.DecimalField(max_digits=8, decimal_places=2, blank=True, null=True)
balance = models.DecimalField(max_digits=8, decimal_places=2, blank=True, null=True)
date = models.DateField(blank=True, null=True)
status = models.CharField(max_length=50)
现在我想做的是每当添加新记录或现有记录更改时,balance
都应该更新为total_amount
和paid_amount
(简单数学)之间的差异,并且根据我的balance
列,我想保存status
为Paid、Partial或Unpaid。
我想避免balance
在我的视图中计算然后保存在数据库中,相反,我想将此部分移交给我的模型,以便我的模型负责处理balance
并且我可以避免我下意识地害怕的错误。
我开始知道这是这样做的
class tbl_payment(models.Model):
document_id = models.ForeignKey(tbl_invoice, on_delete=models.CASCADE)
client_id = models.ForeignKey(tbl_customer, on_delete=models.CASCADE)
total_amount = models.DecimalField(max_digits=8, decimal_places=2, blank=True, null=True)
paid_amount = models.DecimalField(max_digits=8, decimal_places=2, blank=True, null=True)
balance = models.DecimalField(max_digits=8, decimal_places=2, blank=True, null=True)
date = models.DateField(blank=True, null=True)
status = models.CharField(max_length=50)
@property
def balance(self, value):
return self.total_amount - paid_amount
但是我应该通过什么来代替value
?当我试图获得due_amount
这样的价值时
tbl_bulk_payment.objects.get(pk=1).due_amount
它给due_amount() missing 1 required positional argument: 'value'
这样做的正确方法是什么?
解决方案
你必须重写 save() 函数
class tbl_payment(models.Model):
class Status(models.TextChoices):
paid = 'Paid', 'Paid'
partial = 'Partial', 'Partial'
unpaid = 'Unpaid', 'Unpaid'
document_id = models.ForeignKey(tbl_invoice, on_delete=models.CASCADE)
client_id = models.ForeignKey(tbl_customer, on_delete=models.CASCADE)
total_amount = models.DecimalField(max_digits=8, decimal_places=2, blank=True, null=True)
paid_amount = models.DecimalField(max_digits=8, decimal_places=2, blank=True, null=True)
balance = models.DecimalField(max_digits=8, decimal_places=2, blank=True, null=True)
date = models.DateField(blank=True, null=True)
status = models.CharField(max_length=50, choices=Status.choices)
def save(self, *args, **kwargs):
self.balance = self.total_amount - self.paid_amount
if self.balance >= 0:
self.status = Status.paid
elif self.paid_amount == 0:
self.status = Status.unpaid
else:
self.status = Status.partial
super(tbl_payment, self).save(*args, **kwargs)
PS 您的模型类名称不遵循 python 或 Django 命名规则。
class Payment(models.Model)
会更好。
和document_id
=> document
。因为
payment = Payment.objects.get(pk=1)
payment.document_id
在这种情况下payment.document_id
将返回document
实例。(不是文档实例的 ID)。所以document
更像 Django 的风格比document_id
推荐阅读
- .net-core - EF Core:没有 UniqueConstraint 的 PrincipalKey?
- docker - Traefik ratelimit 是否适用于来自其他服务的请求?
- rust - 使用 struct 代替 FnOnce 的函数
- ruby - 在 sinatra 中显示会话超时间隔
- java - ACCESS_FINE_LOCATION 权限是否包含 ACCESS_COARSE_LOCATION 权限
- c# - 多语言 Asp.Net Core 3.1 MVC 应用程序未在 url 中显示语言代码
- python - 访问在 sqlalchemy 中没有键的 json
- ios - iOS 14 - 源应用程序的责任 - 显示广告网络签署的广告
- react-native - 是否有任何流行的日历框架可用于 react native expo?
- docker - Docker:从子目录复制内容不起作用