drf框架中的ModelSerializer序列化组件
03-02 ModelSerializer组件
前面说到了Django REST framework中Serializer序列化组件的使用,使用过的人都会觉得,这样序列化与反序列数据效率是非常低的。
所以在真正的开发环境中,大部分人都是使用的ModelSerializer组件。
相比于Serializer序列化组件,ModelSerializer组件的序列化和反序列化的过程要简单的多
1.自定义类继承ModelSerializer
# serializers.py
from rest_framework import serializers
from . import models
# 整合序列化与反序列化
class UserModelSerializer(serializers.ModelSerializer):
"""
1. 将序列化类与Model类进行绑定
2. 设置序列化与反序列化所有字段(并划分序列化字段与反序列化字段)
3. 设置反序列化的局部与全局钩子
"""
# 自定义反序列化字段,校验规则只能在声明自定义反序列化字段时设置,且write_only=True
re_pwd = serializers.CharField(min_length=3, write_only=True)
class Meta:
# 关联的模型表
model = models.User
# 需要序列化(反序列化的)的表字段
fields = ['name', 'pwd', 're_pwd', 'height']
extra_kwargs = {
'name': {
'required': True,
'min_length': 3,
'error_messages': {
'min)length': '名字不能少于三个字符'
}
},
# 数据库有默认值或可以为空的字段required默认为False,也就是说默认不校验
'height': {
'required': True,
'read_only': True, # 只参与序列化
},
'pwd': {
'required': True,
'write_only': True, # 只参与反序列化
}
}
# 局部钩子
def validate_name(self, value):
if '#' in value.lower():
raise serializers.ValidationError('名字含有非法字符')
return value
# 全局钩子
def validate(self, attrs):
pwd = attrs.get('pwd')
re_pwd = attrs.pop('re_pwd')
if pwd != re_pwd:
raise serializers.ValidationError({'re_pwd': '两次密码不一致'})
return attrs
# ModelSerializer已经帮我们重写了入库方法
2.视图层使用
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from . import models, serializers
class UserAPIView(APIView):
"""
使用方法与Serializer类完全一样,只不过是序列化和反序列化都使用同一个UserModelSerializer类而已
"""
pass
3.总结
"""
单表序列化总结
1. 序列化与反序列化功能可以整合到一个类,该类继承ModelSerializer
2. 继承ModelSerializer类的资源序列化类,内部包含三部分
Meta字类、局部钩子、全局钩子
注:create和update方法ModelSerializer已经重写了,使用时不需要重写
3. 在Meta字类中:
用model来绑定关联的Model类
用fields来设置所有的序列化反序列化字段
用extra_kwargs来设置系统的校验规则
4. 重要的字段校验规则:
read_only校验规则,代表该字段只参与序列化
write_only校验规则,代表该字段只参与反序列化
required校验规则,代表该字段在反序列化时是必填(True)还是选填(False),不能和read_only一起使用(规则冲突)
规则细节:
如果一个字段有默认值或可以为空,没设置required,默认为False,反之为True
如果一个Model字段既没有设置read_only也没有设置write_only,该字段默认参与序列化及反序列化
5. 自定义序列化字段:在Model类中,定义方法属性(返回特殊值,还可以完成连表操作),在序列化类的fields属性中可以选择性插拔
6. 自定义反序列化字段:在Serializer类中,自定义校验字段,校验规则也只能在声明字段时设置,自定义的反序列化字段(如re_pwd),必须设置write_only为True
"""