将 Django F 表达式与 Case、When 表达式一起使用

Using Django F expression with Case, When expression

我有一个像这样的 Django 模型

# app/models.py

class tbl_invoice(models.Model):
    invoice_id                      = models.IntegerField(blank=True, null=True)
    client_id                       = models.ForeignKey(tbl_customer, on_delete=models.CASCADE)
    invoice_number                  = models.IntegerField(blank=True, null=True)
    date                            = models.DateField(blank=True, null=True)
    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_of_payment                 = models.DateField(blank=True, null=True)
    status                          = models.CharField(max_length=50, default='', blank=True, null=True)

我有另一个视图,我正在保存付款记录,我想将 status 更新为 PaidUnpaid取决于用户输入的金额与 balance 之间的差异是 0 还是

目前,这就是我所做的

#app/views.py

if form.is_valid():
    post = form.save(commit=False)
      # rest of the logic goes here
    post.save()
 # this data is saved in another model, after that I update invoice model

tbl_invoice.objects.filter(invoice_id=someIdHere).update(paid_amount=F('paid_amount')+post.amount, 
      date_of_payment=post.date, balance=F('balance')-post.amount, 
      status=Case(
      When(balance=F('balance')-post.amount==0, then=Value("Paid")), 
      When(balance=F('balance')-post.amount!=0, then=Value("Unpaid")), 
   ))

此查询正在将 status 更新为空白。

然而,仅使用 F 表达式来更新 amountbalance 工作正常

tbl_invoice.objects.filter(invoice_id=someIdHere).update(paid_amount=F('paid_amount')+post.amount, 
      date_of_payment=post.date, balance=F('balance')-post.amount

以上语句运行良好

我肯定犯了一些我无法弄清楚的明显错误。 如何将 F 表达式与 Case 一起使用??

首先,请阅读 When document 与您的 Django 版本对应的内容。 可以检查下面的代码作为解决方案:

tbl_invoice.objects.filter(invoice_id=someIdHere).update(paid_amount=F('paid_amount') + post.amount,
                                                     date_of_payment=post.date,
                                                     balance=F('balance') - post.amount,
                                                     status=Case(
                                                         When(balance=post.amount, then=Value("Paid")),
                                                         default=Value("Unpaid")
                                                     ))

为了让它起作用,我们需要将字段以外的所有内容都放在“=”的右侧

status=Case(
    When(balance=post.amount, then=Value("Paid")),
    default=Value("Unpaid")),
)

你也可以

status=Case(
    When(balance__gt=post.amount, then=Value("Paid")), 
    When(balance__lte=post.amount, then=Value("Unpaid")), 
)