django-rest-framework入门,我在验证方面遇到了一些麻烦。
我有一个基本模型,并且已将验证器应用于其字段的copple(常规MaxLengthValidator
和自定义RegexValidator
,最终像这样:
class ZipCodeValidator(RegexValidator):
regex = '^([0-9]{5})$'
message = u'Invalid ZipCode.'
class User(AbstractUser, BaseUser):
"""
Custom user model
"""
# ... other fields ...
zipcode = models.CharField(
max_length=5, blank=True, validators=[ZipCodeValidator()]
)
description = models.TextField(
null=True, blank=True, max_length=1000, validators=[MaxLengthValidator(1000)]
)
然后,我创建了一个映射到此模型的
ModelSerializer
,还有一些其他字段和方法。全部由一个非常简单的`RetrieveUpdateAPIView服务。我注意到未调用验证程序(我可以在邮政编码字段中输入任何内容,或者超过1000个字符作为描述)。
快速而肮脏的解决方案是在序列化器级别覆盖两个字段,并在此处为它们分配验证器:
class UserSerializer(serializers.ModelSerializer):
zipcode = serializers.WritableField(
source='zipcode', required=False, validators=[ZipCodeValidator()]
)
description = serializers.WritableField(
source='description', required=False, validators=[MaxLengthValidator(1000)]
)
这很好,但我不太喜欢。我宁愿这种验证在模型级别进行以更安全(我不介意在序列化程序上进行自定义或其他验证,但是在所有情况下都必须执行这些规则)。由于序列化器的工作方式与django表单非常相似,因此我希望它们在保存之前先调用模型的
clean
&cie方法,但是快速浏览source似乎表明事实并非如此。这有点烦人,如果我想确保验证总是发生的话,它会迫使我重复很多字段代码,而我宁愿将其保持为DRY。
我可能会丢失一些东西,但是有没有一种干净的方法来确保那些验证程序在更新模型之前由序列化程序运行?
编辑:仔细检查了源代码,结果发现实例的
full_clean
方法确实已被 View 调用,然后再将其保存到数据库中,从而最终运行了模型的验证器。关于那些为什么似乎没有运行,仍然不知所措。 最佳答案
这对我有用:
class ZipCodeValidator(RegexValidator):
regex = r'^[0-9]{5}$'
message = 'Invalid ZipCode.'
class MyModel(models.Model):
zipcode = models.CharField(max_length=5, blank=True, validators=[ZipCodeValidator()])
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
>>> s1 = MyModelSerializer(data={'zipcode': '34234'})
>>> s1.is_valid()
True
>>> s2 = MyModelSerializer(data={'zipcode': 'f3434'})
>>> s2.is_valid()
False
>>> s2.errors
{'zipcode': [u'Invalid ZipCode.']}
关于python - Django Rest框架和模型验证,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23106046/