【问题标题】:update django models column based on other column根据其他列更新 django 模型列
【发布时间】:2020-12-03 13:00:23
【问题描述】:

我有一个类似的模型

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 之间的差异(简单数学),并基于我的 @ 987654325@ 栏目,我想将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'

这样做的正确方法是什么??

【问题讨论】:

    标签: django django-models orm


    【解决方案1】:

    你必须重写 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)
    

    附:您的模型类名称不遵循 python 或 Django 命名规则。 class Payment(models.Model) 会更好。

    和document_id => document。因为

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

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

    【讨论】:

    • 是的,它有帮助!!!谢谢!!但是有没有其他方法可以做到这一点而不必覆盖 save() 方法?只是想知道
    • 可以通过网页到数据库的工作流程来完成(HTML => View => Form => Model)。如果您使用forms.py,则可以在SomeModelForm 等某些表单类中完成。并且可以在views.py 完成(不推荐)。但在这种情况下,models.py 是合适的地方。
    • 我想我现在会坚持上面的答案,它解决了问题并且很方便......:D
    • 有几种方法可以放置业务逻辑 :) readmore => sunscrapers.com/blog/where-to-put-business-logic-django
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-19
    • 2021-10-19
    • 2022-08-18
    相关资源
    最近更新 更多