【问题标题】:Using models clean method for fields validation使用模型清理方法进行字段验证
【发布时间】:2020-02-19 12:27:01
【问题描述】:

在将可用项目列表保存到数据库之前,我需要检查模型字段。

models.py

class Vendors(models.Model):
    COUNTRY_CHOICES = tuple(countries)
    ...
    country = models.CharField(max_length=45, choices=COUNTRY_CHOICES)
    ...

模型保存类

class CsvToDatabase(APIView):

    def post(self, request, format=None):
        data = request.data
        for key, vendor in data.items():
            Vendors(
                ...,
                country=vendor['Country'],
                ...,

            ).save()

        return Response({'received data': request.data,
                         'message': 'Vendors from vendors_list were successfully added to the database'})

为了验证,我在模型中添加了 clean 方法

def clean(self):
    if self.country not in [x[1] for x in countries]:
        raise ValidationError(detail="Country name does not match to the country list ")

但它不起作用

下一步我将相同的代码添加到方法 save

def save(self):
    if self.country not in [x[1] for x in countries]:
        raise ValidationError(detail="Country name does not match to the country list ")

它有效,但我读到在保存方法中使用验证是不正确的。以及正确的使用方法——clean,为什么在我的情况下它不起作用?

【问题讨论】:

  • 正确的方法确实是使用clean(),但是模型上的clean()方法不会自动调用。当您清理模型的ModelForm(通过检查form.is_valid())或验证ModelSerializer 时,它会被调用。您也可以自己调用它。创建Vendors 对象,首先调用full_clean()(并捕获ValidationError),然后才调用save()。注意:如果你调用full_clean(),模型已经验证了国家设置是否正确,你不需要在clean()中添加。

标签: python django django-rest-framework


【解决方案1】:

请参阅model validation,了解有关验证模型如何工作的完整说明。

简而言之:要验证一个对象,您需要在该对象上调用full_clean()。这不会自动发生!它发生在:

  • 您使用ModelForm 并在表单上调用is_valid()
  • 您在 DRF 中使用 ModelSerializer 并在序列化程序上调用 is_valid()
  • 你显式调用full_clean()

在您的情况下,只需创建对象,调用full_clean(),然后调用save()。请注意,您甚至不必添加自己的检查(clean() 方法),因为当在字段上设置 choices 时,Django 会在 clean_fields() 期间自动执行对有效选择的检查:

v = Vendors(country=vendor['country'], ...)
try:
    v.full_clean()
except ValidationError as e:
    # do something e.g. return error response
v.save()
return Response(...)

【讨论】:

  • 太好了,它有效,对我来说是非常有用的信息。对我来说还有一件事-如何捕获异常?现在我有一个来自干净模型方法的异常,我想使用来自 POST 类方法的异常。我为此创建了一个新问题。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2020-06-22
  • 1970-01-01
  • 2019-08-22
  • 2015-03-19
  • 1970-01-01
  • 2019-06-21
  • 2012-10-08
  • 2012-03-02
相关资源
最近更新 更多