序列化主要两个功能:
1.用于对用户请求数据进行验证;
1.用于对用户请求数据进行验证;
2.对于数据库中的数据(queryset类型、model对象)进行序列化。
一.对于后端程序从数据库拿到的数据(queryset、model对象)进行序列化
models.py # 准备工作:表结构
from django.db import models
class Menu(models.Model):
name = models.CharField(max_length=32)
class Group(models.Model):
title = models.CharField(max_length=32)
mu = models.ForeignKey(to='Menu',default=1)
class UserInfo(models.Model):
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
group = models.ForeignKey('Group')
roles = models.ManyToManyField('Role')
class Role(models.Model):
name = models.CharField(max_length=32)
以下是视图部分内容
########### 1.根据model表来序列化########################
class UserSerializer(serializers.ModelSerializer): # 继承自ModelSerializer类
'''序列化数据的类,根据model表来获取字段'''
x1 = serializers.CharField(source='name') # 自定义字段,必须定义source
class Meta:
model = models.UserInfo
# fields = '__all__'
fields = ['name','pwd','group','x1']
depth = 3 # 此字段表示查看嵌套几层的数据,不建议太大,性能损耗
class UserView(APIView):
'''用户相关视图'''
def get(self,request,*args,**kwargs):
user_list = models.UserInfo.objects.all() # 从数据库拿到的query类型数据
ser = UserSerializer(instance=user_list,many=True) # 序列化的类,拿到一个对象
print(ser.data) # 序列化之后的json格式的数据
return Response(ser.data)
####### 2.自己定义要序列化哪些字段 含:单表、一对多、多对多关系###########
class MyCharField(serializers.CharField):
"自定义模板中需要序列化字段的类,目的是自定制多对多关系中的返回值"
def to_representation(self, value):
# value代表,当前user对象关联的对象
role_list = []
for each in value:
role_list.append(each.name)
return role_list
# 建立一个继承自serializers.Serializers的类,这种需要自己定义需要序列化的字段
class UserSerializer(serializers.Serializer):
"相当于建立一个序列化的模板,来规定需要的字段"
# 单表中的字段
id = serializers.CharField() # obj.id (要是没有写source=xxx,就会执行obj.id)
name = serializers.CharField()
pwd =serializers.CharField()
#跨表查询(多对一)
group = serializers.CharField(source='group.title') # source拿到当前对象的group属性的,
menu_ttile = serializers.CharField(source='group.mu.name')
menu_id = serializers.CharField(source='group.mu.id') # 字符串内部做判断,可执行,则会执行
# 多对多(自定制当前字段序列化之后返回中的内容)
# role_list = serializers.CharField(source='roles.all')
# 这种,在最后显示的时候,只能做成这样子 "role_list": "<QuerySet [<Role: Role object>, <Role: Role object>]>"
# 方法1:定制to_representation方法
# 针对上种情况,定制返回值,继承自(serializers.CharField)
# role_list = MyCharField(source='roles.all') # 看上边自定制的类MyCharField,其中重写了to_representation方法
# 方法2:(其实返回的内容,还是需要自定义MyCharField()类定制返回的值,只是value指定每个role对象,)
# role_list = serializers.ListField(child=serializers.CharField(),source='roles.all')
# 方法3:(也需要自定制get_字段名,定义此子字段返回值,定制性更好,=====推荐使用====)
role_list = serializers.SerializerMethodField()
def get_role_list(self,obj):# obj就是当前user对象
li = []
roles_list = obj.roles.filter(id=1) # 这里可以添加过滤的信息
roles_list = obj.roles.all()
for i in roles_list:
li.append({'id':i.id,'name':i.name})
return li
class UserView(APIView):
def get(self,request,*args,**kwargs):
user_list = models.UserInfo.objects.all() # 从数据库拿到的数据
ser = UserSerializer(instance=user_list,many=True)
print(ser.data)
return Response(ser.data)
二、对于前端POST提交的数据库进行验证,类似与form验证
这个也是两种情况,类似与序列化,一种是根据表来做,另一种是细化到字段
########### 序列化功能二:对于请求数据做验证#############################
class PassworValidator():
'''自定义验证密码的验证规则类'''
def __init__(self,base): # base,就是验证规则,可以定义为正则表达式,或者是一个函数吧。
# def __init__(self): # base,就是验证规则,可以定义为正则表达式,或者是一个函数吧。
self.base = base
def __call__(self, value): # 调用的时候,会执行__call__方法,value,就是前段post提交过来的数据
'''在这个函数中做验证,然后返回'''
print(value,'value的值是')
if value != self.base:
# if value != 1:
message = '这个字段必须是%s'%self.base
raise serializers.ValidationError(message) # 这里抛出来的错误,就会被ser.errors接收,展示给用户
# 第一种:如果是自己定义的序列化的类(与下边的验证类二选一)
class UserSerializer(serializers.Serializer):
name = serializers.CharField(min_length=5)
pwd = serializers.CharField(error_messages={'required':'密码不能为空'},validators=[PassworValidator('666'),]) # 这里的666是验证规则,也可以不写,直接在上边类的__call__方法中写
# 第二种:直接继承自modelSerializer类的序列化类 (与上边的验证类二选一)
class UserSerialazer(serializers.ModelSerializer):
class Meta:
model = models.UserInfo
fields = "__all__"
# 定义字段的验证规则
extra_kwargs = {
'name':{'min_length':3},
'pwd':{'validator':[PassworValidator('666')],} # PassworValidator中,可以传参数,也可以不传参数。
}
class UserView(APIView):
def get(self,request,*args,**kwargs):
user_list = models.UserInfo.objects.all()
ser = UserSerializer(instance=user_list,many=True)
print(ser.data)
return Response(ser.data)
def post(self,request,*args,**kwargs):
ser = UserSerializer(data=request.data) # 生成一个对象
if ser.is_valid():
ret = ser.data # ser.data是ReturnDict类型,这个类型继承自OrderedDict,OrderedDict继承自dict
ret = ser.validated_data # ser.data是ReturnDict类型,这个类型继承自OrderedDict,OrderedDict继承自dict
else:
print(ser.errors)
print(ser.error_messages)
return Response('POST 请求,相应内容')