django中restframework中的序列化

模型类:

class UserInfo(models.Model):
    user_type_choice = (
        (1, '普通用户'),
        (2, 'VIP'),
        (3, 'SVIP'),
    )
    user_type = models.IntegerField(choices=user_type_choice)
    username = models.CharField(max_length=32, unique=True)
    password = models.CharField(max_length=64)
    group = models.ForeignKey('UserGroup', on_delete=models.CASCADE)
    roles = models.ManyToManyField('Role')

class Role(models.Model):
    title = models.CharField(max_length=32)

class UserGroup(models.Model):
    title = models.CharField(max_length=32)

总结:

     1. 写类继承ModelSerializer或者Serializer

     2. 字段:自定义字段,通过函数自定义字段

一。使用ModelSerializer序列化

   1. 获取所有字段(关联的字段或多选的字段只显示数字)

class UserInfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = "__all__"

  2. 获取局部的字段(关联的字段或多选的字段只显示数字)

class UserInfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = ['id', 'username']

 3. 自定义字段,并添加进去(这里可以解决choice字段带来的只显示数字的问题和多对一的问题)

from rest_framework import serializers
class UserInfoSerializer(serializers.ModelSerializer):
    ooo = serializers.CharField(source='get_user_type_display') # 自定义字段,解决choice问题
    group_title = serializers.CharField(source='group.title')  # 自定义字段,关联group的title字段
    class Meta:
        model = models.UserInfo
        fields = ['id', 'username', 'ooo']      # 这里要加自定义的字段名称

 4. 利用函数自定义字段(可以解决一对多的问题,还有其他自定义问题)

from rest_framework import serializers
class UserInfoSerializer(serializers.ModelSerializer):
    ooo = serializers.CharField(source='get_user_type_display') #自定义字段
    rls = serializers.SerializerMethodField()
    class Meta:
        model = models.UserInfo
        fields = ['id', 'username', 'ooo', 'rls']      # 这里要加自定义的字段名称

    def get_rls(self, row):                 # get开头,字段名结尾,传入row(这个是每一行)
        role_obj_list = row.roles.all()     # 角色对象
        ret = []                            # 要返回的值
        for item in role_obj_list:
            ret.append({'id':item.id, 'title':item.title})
        return ret

 结果:

 5. (重要)使用depth来获取表的深度,深度是为1时是当前表ForeignKey或ManyToManyField关联的下一层的所有数据,深度为2时是当前表关联的表的所有ForeignKey或ManyToManyField的所有数据。(当然也可以和前面的情况一起使用)

from rest_framework import serializers
class UserInfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = '__all__'      # 这里要加自定义的字段名称
        depth = 1  #0 ~ 10      # 深度为1,获取ForeignKey或ManyToManyField下的所有数据

 结果:

二。改变要显示的字段的名称(不是改变值),下面使用的是Serializer类,是ModelSerializer的父类

  1. 自定义一个序列化类,里面写要序列化的字段,如果不加source参数,则类的变量名就是字段的名称。如果加了,则类的变量名是显示的序列化的字段名称。

from rest_framework import serializers
class UserInfoSerializer(serializers.Serializer):
    xxx = serializers.CharField(source='user_type')   # source是显示数据库的那个字段,
    username = serializers.CharField()              # 用变量指定也可以,用source指定也可以,优先是变量指定,然后是source(这个可以变字段的名称)
    password = serializers.CharField()

class Ser(APIView):
    authentication_classes = []
    permission_classes = []

    def get(self, request, *args, **kwargs):
        users = models.UserInfo.objects.all()
        ser = UserInfoSerializer(instance=users, many=True)

        ret = json.dumps(ser.data, ensure_ascii=False)
        return HttpResponse(ret)

 2. 显示如图

   

3. xxx,也就是user_type显示的是数字而不是文字(普通用户,vip等),那么要显示的话,就要让source如下改变

    source = ‘get_字段名称_display'        这里字段是user_type,所以就是 get_user_type_display,其他的不变

from rest_framework import serializers
class UserInfoSerializer(serializers.Serializer):
    xxx = serializers.CharField(source='get_user_type_display')   # source是显示数据库的那个字段,
    ooo = serializers.CharField(source='user_type')    #有choice的解决方案
    username = serializers.CharField()              # 用变量指定也可以,用source指定也可以,优先是变量指定,然后是source(这个可以变字段的名称)
    password = serializers.CharField()

4, 显示如图

三。获取关联的字段:

1. 这个是多对一的解决方案,多的一方获取一的一方的关联字段,只要在source里面写入外键名称,再通过外面名称关联其他表格

class UserInfoSerializer(serializers.Serializer):
    password = serializers.CharField() 
    # 有ForeignKey的解决方案
    gp = serializers.CharField(source='group.title') # 多的一方引用一的一方的关联字段

结果:

 

2. 这个是一对多的解决方案,一的一方获取多的一方的关联字段,定义一个函数,这个函数以get开头,以字段名称结尾,然后传入每一行的数据row,然后再里面处理每一行的数据再返回。

class UserInfoSerializer(serializers.Serializer):
    username = serializers.CharField()              # 用变量指定也可以,用source指定也可以,优先是变量指定,然后是source(这个可以变字段的名称)
    password = serializers.CharField()
    gp = serializers.CharField(source='group.title') # 多的一方引用一的一方的关联字段
    rls = serializers.SerializerMethodField()

    def get_rls(self, row):             # get开头,字段名结尾,传入row(这个是每一行)
        role_obj_list = row.roles.all() # 角色对象
        ret = []                        # 要返回的值
        for item in role_obj_list:
            ret.append({'id':item.id, 'title':item.title})
        return ret

结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值