序列化与反序列功能可以整合成一个类,该类继承ModelSerializer
例如,我们以及有了一个数据库模型类User
class User(models.Model):
sex_choice = ((0,"男"),(1,"女"))
name = models.CharField(max_length=32,unique=True)
age = models.IntegerField(null=True)
height = models.DecimalField(max_digits=5,decimal_places=2,null=True)
sex = models.IntegerField(choices=sex_choice,default=0)
icon = models.ImageField(upload_to="icon",default="default.png")
pwd = models.CharField(max_length=32,null=True)
继承ModelSerializer类的资源序列化类,内部包含三部分
在Meta子类中:
重要的字段校验规则:
自定义序列化字段:
class User(models.Model):
# 自定义插拔序列化字段:替换了在Serializer类中自定义的序列化字段(SerializerMethodField)
# 自定义插拔序列化字段一定不参与反序列化过程
@property
def gender(self):
return self.get_sex_display()
自定义反序列化字段:
'''serializers.py'''
# 重点 ModelSerializer
from rest_framework.serializers import ModelSerializer
from .. import models
# 整合序列化与反序列化
class UserModelSerializer(ModelSerializer):
# 将序列化类与Model类进行绑定
# 设置序列化与反序列化所有字段(并划分序列化字段与反序列化字段)
# 设置反序列化的局部与全局钩子
# 自定义反序列化字段,校验规则只能在声明自定义字段时设置,且一定是write_only
re_pwd = serializers.CharField(min_length=3, max_length=64, write_only=True)
class Meta:
# 用model来绑定关联的Model类
model = models.User
# 用fields来设置所有的序列化反序列化字段
fields = ['name',"age","pwd","re_pwd","gender","sex"]
# 用extra_kwargs来设置系统的校验规则,只有反序列化的时候能用到
extra_kwargs = {
"name":{
"required":True,
'min_length': 3,
'error_messages': {
'min_length': '太短'
}
},
"age": {
"required": True, # 数据库有默认值或可以为空字段,required默认为False
'min_value': 0,
},
"pwd": {
"required": True, # 数据库有默认值或可以为空字段,required默认为False
"write_only":True,
},
"gender": {
"read_only":True,
},
"sex": {
"write_only":True,
},
}
def validate_name(self, value):
if 'g' in value.lower():
raise serializers.ValidationError('名字中不能有g')
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已经帮我们重写了入库方法
'''views.py'''
from . import models
from .utils import serializers
from rest_framework import status
'''ModelSerializer类'''
class UserV2APIView(APIView):
def get(self,request,*args,**kwargs):
pk = kwargs.get("pk")
if pk:
user_obj = models.User.objects.filter(pk=pk).first()
if not user_obj:
return Response({
'status': 1,
'msg': '单查 error'
})
# 完成序列化
user_data = serializers.UserModelSerializer(user_obj, many=False).data
return Response({
'status': 0,
'msg': '单查 ok',
'results': user_data
})
else:
user_query = models.User.objects.all()
# 完成序列化
user_list_data = serializers.UserModelSerializer(user_query, many=True).data
return Response({
'status': 0,
'msg': '群查 ok',
'results': user_list_data
})
def post(self,request,*args,**kwargs):
request_data = request.data
user_ser = serializers.UserModelSerializer(data=request_data)
# 校验失败,直接抛异常,反馈异常信息给前台,只要校验通过,代码才会往下执行
result = user_ser.is_valid()
if result:
user_obj = user_ser.save()
return Response({
'status': 0,
'msg': 'ok',
'results': serializers.UserModelSerializer(user_obj).data
})
else:
# 校验失败,返回错误信息
return Response({
'status': 1,
'msg': user_ser.errors
}, status=status.HTTP_400_BAD_REQUEST)
原文:https://www.cnblogs.com/XuChengNotes/p/11902095.html