django 如何获取在模型的clean方法中从相关对象计算的属性的传入值

jckbn6z7  于 2023-01-18  发布在  Go
关注(0)|答案(1)|浏览(146)

我有两个模型,一个Invoice模型和一个LineItem模型。LineItem模型看起来像这样:

class LineItem(models.Model):
    unit_price = models.DecimalField()
    quantity = models.IntegerField()
    invoice = models.ForeignKey(Invoice)

    @property
    def lineitem_total(self): return self.unit_price * self.quantity

Invoice模型还有一个total属性,该属性返回所有相关行项目的总和。
现在,当与发票相关的行项目更新时,我需要验证发票上的total属性是否超过了某个最大值。但是,发票上的clean()方法在相关行项目更新之前触发,因此它仍然返回旧值。我需要在模型本身而不是表单上进行验证。
是否有方法验证行项目?
我尝试过将验证放在Invoice模型的clean()方法中,但是total属性仍然返回行项目更新之前的旧值。
我还尝试过在Invoice模型的save()方法中引发ValidationError,但是返回了500错误。

5n0oy7gb

5n0oy7gb1#

您可以在LineItem模型表单中这样尝试(代码注解中的解释):

class SomeFormItem(forms.ModelForm):
   ...
   def save(self, commit=False):
       instance = super().save(commit=False)
       total = instance.invoice.total  #  get total of line items (assuming used using reverse query)

       if self.instance.pk and ('quantity' in self.changed_data or 'unit_price' in self.changed_data):  # if we are editing already existing lineitem and total has been changed
           total += (self.cleaned_data['unit_price'] - self.data['unit_price']) * (self.cleaned_data['quantity'] - self.data['quantity'])  # self.cleaned_data contains new information and self.data contains old information and calculating the difference only
       else:
           total += self.cleaned_data['quantity'] * self.cleaned_data['unit_price']

       if total  > SOME_NUMBER:
            raise ValidationError()
       return super().save(commit=commit)

更多信息可以在文档中找到。

相关问题