字段级验证
你可以通过向 Serializer
子类添加 .validate_<field_name>
方法来指定自定义字段级验证。这些与 Django 的 form
上的 .clean_<field_name>
方法类似。
这些方法只有一个参数,就是需要验证的字段值。
您的 validate_<field_name>
方法应返回验证值或引发 serializers.ValidationError
。
例子:
from rest_framework import serializers
class BlogPostSerializer(serializers.Serializer):
title = serializers.CharField(max_length=100)
content = serializers.CharField()
def validate_title(self, value):
"""
检查 title 字段 是否含有 "Django" 单词.
"""
if 'django' not in value.lower():
raise serializers.ValidationError("Blog post is not about Django")
return value
在 shell 中测试下:
>>> serializer = BlogPostSerializer(data={'title': 'django', 'content': 'bar'})
>>> serializer.is_valid()
True
>>> serializer = BlogPostSerializer(data={'title': 'foobar', 'content': 'bar'})
>>> serializer.is_valid()
False
>>> serializer.errors
ReturnDict([('title', ['Blog post is not about Django'])])
注意:如果你的序列化程序中声明的 <field_name>
参数为 required = False
,那么如果未包含该字段,则不会执行此验证步骤。
对象级验证
如果要对多个字段进行其他的验证,请将一个名为 .validate()
的方法添加到您的 Serializer
子类中。这个方法只有一个参数,它是一个字段值(field-value)的字典。如果有必要,它应该引发一个 ValidationError
,或者只是返回验证的值。
例子:
from rest_framework import serializers
class LoginSerializer(serializers.Serializer):
username = serializers.CharField(max_length=100)
password1 = serializers.CharField(max_length=16)
password2 = serializers.CharField(max_length=16)
def validate(self, data):
"""
检查两次密码输入是否一致
"""
if data['password1'] != data['password2']:
raise serializers.ValidationError("两次密码输入不一致")
return data
在 shell 中测试下:
>>> from myapp.serializer import LoginSerializer
>>> serializer = LoginSerializer(data={'username': 'foobar', 'password1': '12345', 'password2': 'abcde'})
>>> serializer.is_valid()
False
>>> serializer.errors
ReturnDict([('non_field_errors', ['两次密码输入不一致'])])
验证器
序列化器上的各个字段可以包含验证器,方法是在字段实例上声明它们,例如:
from rest_framework import serializers
# 自定义验证器
def password_validators(value):
if len(value) < 6:
raise serializers.ValidationError('密码需大于6位')
class LoginSerializer(serializers.Serializer):
username = serializers.CharField(max_length=100)
# validators 参数指定使用哪个验证器
password1 = serializers.CharField(validators=[password_validators])
password2 = serializers.CharField(validators=[password_validators])
在 shell 中测试下:
>>> from myapp.serializer import LoginSerializer
>>> serializer = LoginSerializer(data={'username': 'foobar', 'password1': '12345', 'password2': '12345'})
>>> serializer.is_valid()
False
>>> serializer.errors
ReturnDict([('password1', ['密码需大于6位']), ('password2', ['密码需大于6位'])])