RESTFrame序列化问题
序列化主要两个功能:
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 请求,相应内容')