根据其他列更新django模型列

w8rqjzmb  于 2023-07-01  发布在  Go
关注(0)|答案(1)|浏览(99)

我有一个模型

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_amountpaid_amount之间的差异(简单的数学),并且基于我的balance列,我想将status保存为PaidPartialUnpaid
我不想在视图中计算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'
正确的做法是什么??

z31licg0

z31licg01#

你必须重写clean()函数。https://docs.djangoproject.com/en/4.2/ref/models/instances/#django.db.models.Model.clean
Model.clean() ...修改模型的属性...

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 clean(self):
            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

P.S.你的Model类名没有遵循Python或Django的命名规则。class Payment(models.Model)会更好。
document_id => document。因为

payment = Payment.objects.get(pk=1)
payment.document_id

在这种情况下,payment.document_id将返回document示例。(不是文档示例的ID)。所以documentdocument_id更像Django风格

相关问题