Django 模型条件验证

Posted

技术标签:

【中文标题】Django 模型条件验证【英文标题】:Django Model conditional Validations 【发布时间】:2021-08-05 07:55:20 【问题描述】:

我已经制作了一个 API,客户通过发布请求发送他/她的付款详细信息,因此需要在模型级别验证此数据,我如何通过将模型字段与其他模型字段进行比较来验证模型字段例如:

models.py
Orders(models.Model):
   amount = models.DecimalField(max_digits=19, decimal_places=4)
   currency = models.CharField(max_length=3,choices=[('INR','INR')]) more choices are to be added 
   payee_pan = models.CharField(max_length=10)

需要验证:如果货币为“INR”且金额大于 50000,则必须存在 payee_pan。 为了验证它,我在将模型对象保存在views.py中时使用了model.full_clean()

views.py
    try:
        orders.full_clean()
    except ValidationError:
        return Response("Error message":"invalid request body")
    else:
        orders.save()

如果有人在这方面帮助我,我将不胜感激,因为我在这一点上停留了这么久。enter code here

【问题讨论】:

【参考方案1】:

您可以通过覆盖模型上的clean 方法来执行此类验证(参考Validating objects [Django docs]):

from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _


class Orders(models.Model):
    amount = models.DecimalField(max_digits=19, decimal_places=4)
    currency = models.CharField(max_length=3,choices=[('INR','INR')])
    payee_pan = models.CharField(max_length=10)
    
    def clean(self):
        if self.currency == 'INR' and self.amount > 50000 and not self.payee_pan:
            raise ValidationError(_('Payee Pan is required'))

注意:理想情况下,模型名称应该是单数(如果您检查模型的详细名称复数,它会以 Orderss 目前有一个额外的s)。因此它应该是 Order 而不是 Orders

【讨论】:

非常感谢@AbdulAzizBarkat 的建议,它工作得很好,我会如你所说的那样进行必要的更改。【参考方案2】:
from django.db import models
from django.core.exceptions import ValidationError


class Orders(models.Model):
    amount = models.DecimalField(max_digits=19, decimal_places=4)
    currency = models.CharField(max_length=3, choices=[('INR','INR')]) # more choices are to be added 
    payee_pan = models.CharField(max_length=10)

    class Meta:
        verbose_name = "Order"
        verbose_name_plural = "Orders"

    def clean(self):
        if self.currency == 'INR' and self.amount > 50000 and not self.payee_pan:
            raise ValidationError(
                "payee_pan": "Payee Pan field is required"
            )
    
    def save(self, *args, **kwargs):
        self.full_clean()
        return super().save(*args, **kwargs)

您可以删除视图中的 try-except 块。调用 save() 方法将调用底层的 full_clean() 方法,该方法将调用任何验证钩子。

【讨论】:

非常感谢 @GabrielRockson 的帮助。 不客气@AmitYadav,你能接受它以便下次也帮助其他人吗?

以上是关于Django 模型条件验证的主要内容,如果未能解决你的问题,请参考以下文章

Django 模型验证

在 Django 中分离表单输入和模型验证?

没有用户模型的 Django 基于令牌的身份验证

Django 验证

可以在 django 模型验证器中使用多个值吗?

相关领域的 Django 模型验证