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 请求,相应内容')


猜你喜欢

转载自blog.csdn.net/baifengqing/article/details/80037299
今日推荐