DJango反序列化器的参数效验
Posted wonderlandlove
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DJango反序列化器的参数效验相关的知识,希望对你有一定的参考价值。
ps:我是一名新手,代码基本靠抖,偶尔代码顺畅,只因运气帮忙。
两种定义序列化器的方式
#定义 serializers.py
class UserSerializer(serializers.ModelSerializer):
"""
用户数据序列化器
"""
class Meta:
model = User
#所有字段
fields = "__all__"
#选择个别字段
#fields = (‘id‘, ‘name‘, ‘phone‘)
#序列化使用 view.py
query_set = User.objects.all()
serializer = UserSerializer(query_set, many=True)# 传入对象集时需指定many=True
serializer.data
#反序列化使用
通过data传入字段数据 通过is_valid方法校验参数合法性 save()保存入库
serializer = UserSerializer(data = data)
if serializer.is_valid():
serializer.save
第二种反序列化方法
自定义验证行为:
1. validate_字段名:在序列化器中添加方法,方法名validate_字段名,参数为value,对value做校验,
raise serializers.ValidationError(‘XXXX‘),返回值value
2. validate:在序列化器中添加validate方法,可同时对多个字段进行验证
参数为attrs,从attrs中获取值,然后进行逻辑处理,抛出异常,返回值attrs
3.validator:在序列化器上方编写函数,参数value,对value校验,抛出异常
在序列化器字段中加入validator选项参数,为列表形式,值为函数名。
4.REST framework提供的validators:
UniqueValidator单字段唯一:字段中设置,参数为queryset
UniqueTogetherValidation联合唯一:class Meta中设置,参数queryset和fields
保存:如果验证成功,向基于validated_data完成数据对象的创建,可以通过create和update来实现
1.新建:在序列化器中重写create方法,参数为validate_data,
返回值为模型类.objects.create(**validated_data)
2.更新:在序列化器中重写update方法,参数instance即要更新的实例和validate_data
对validate_data字典获取其值,对无传递值给予默认值 instance.字段,并赋给instance.字段,然后调用instance.save()提交,返回值instance
注意点:
①实现了create和update方法后,在反序列化时既可以序列化对象.save()返回数据对象实例并保存或更新到数据库
②调用save时,如果有传instance实例,则调用update方法更新数据,否则调用create方法新建数据。
③调用save可传参,参数可从validated_data中获取
④如果没有传递所有required字段,会抛出验证异常,可通过使用partial=True实现部分字段更新
模型类序列化器ModelSerializer
可基于模型类自动生成一系列字段,会自动生成valiators和实现了默认的create和update方法
定义函数 validate_:对<field_name>字段进行验证
# 模型: models.py
class User(models.Model):
username = models.CharField(max_length=20)
password = models.CharField(max_length=30)
# 声明表名
class Meta:
db_table = "carousel"
# 序列化器:serializer.py
class UserSerializer(serializers.Serializer):
"""用户个人数据序列化器"""
#这里的字段设计要和model里面的一致
username =serializers.CharField(max_length=20, write_only=True)
def validate_name(self, value):
# 校验部门名称
if not re.match(‘^[u4e00-u9fa5]+$‘, value):
raise ValidationError(‘部门名称只能为中文‘)
return value
validate:同时对多个字段进行比较验证
# 模型: models.py
class User(models.Model):
username = models.CharField(max_length=20)
password = models.CharField(max_length=30)
# 序列化器: serializer.py
class UserSerializer(serializers.Serializer):
password = serializers.CharField(max_length=30, write_only=True)
password2 = serializers.CharField(max_length=30, write_only=True)
def validate(self, attrs):
# 校验两次输入的密码是否正确
password = attrs[‘password‘]
password2 = attrs[‘password2‘]
if password != password2:
raise serializers.ValidationError(‘两次输入的密码不一样‘)
return attrs
#这个时候视图密码的代码就剩了好多 view.py
from rest_framework.generics import CreateAPIView
from .myser import UserCreaterSerializers
class UserView(CreateAPIView):
"""注册用户"""
# 指定用哪个序列化器
serializer_class = UserCreaterSerializers
这是我写的一个的序列化操作
# 序列化
class UserCreaterSerializers(serializers.Serializer):
# 用户id 只允许读
id = serializers.IntegerField(read_only=True)
"""定义要传入的参数"""
# 用户名
username = serializers.CharField(
min_length=2,
max_length=20,
error_messages={
‘min_length‘: ‘用户名太短‘,
‘max_length‘: ‘用户名太长‘
}
)
password = serializers.CharField(
write_only=True,
min_length=6,
max_length=20,
error_messages={
‘min_length‘: ‘密码不能少于6个字符‘,
‘max_length‘: ‘密码不能超过20个字符‘
}
)
password2 = serializers.CharField(
write_only=True,
min_length=6,
max_length=20,
error_messages={
‘min_length‘: ‘密码不能少于6个字符‘,
‘max_length‘: ‘密码不能超过20个字符‘
}
)
phone = serializers.CharField(
max_length=11,
min_length=11,
error_messages={
‘max_length‘: ‘输入的电话号码格式不对‘,
‘min_length‘: ‘输入的电话号码格式不对‘
}
)
# 字段验证 验证用户名
def validate_username(self, value):
"""
对用户名进行合法检查
:param value:要验证的用户名
:return:如果验证通过返回value,否则抛出异常
"""
# 用户名必须包含字母
if not re.search(r‘[a-zA-Zd_]‘, value):
raise serializers.ValidationError(‘用户名中必须包含字母‘)
# 验证用户名是否存在
if User.objects.filter(username=value):
raise serializers.ValidationError(‘用户名已存在‘)
return value
#验证手机号码
def validate_phone(self, value):
‘‘‘
验证手机号
:param value: 要验证的手机号
:return:如果手机号正确返回value,否则抛出异常
‘‘‘
if re.search(r‘1[3567]d{9}$‘, value):
return value
else:
raise serializers.ValidationError(‘手机号码不符合规范‘)
#多条数据验证,密码验证
def validate(self, attrs):
‘‘‘
验证两次输入的密码
:param attrs: 同时对多个字段进行比较验证
:return:如果密码比对正确返回attrs,也就是定义的哪一个密码,否则抛出异常
‘‘‘
password = attrs[‘password‘]
password2 = attrs[‘password2‘]
if password != password2:
raise serializers.ValidationError(‘两次输入的密码不一样‘)
return attrs
def create(self, data):
"""
保存数据
:param data: 一个包含用户名、密码等信息的字典
:return: 返回一个user对象
"""
user = User()
user.username = data.get(‘username‘)
user.phone = data.get(‘phone‘)
user.password = data.get(‘password‘)
user.save()
return user
以上是关于DJango反序列化器的参数效验的主要内容,如果未能解决你的问题,请参考以下文章