Django REST framework序列化(一)-------对QuerySet进行序列化

解析器是对请求体数据进行解析

序列化有两个用处:
1.对 QuerySet进行序列化(json不能序列化QuerySet类型)
2.对请求数据进行校验

Django也自带了一个对QuerySet进行序列化的方法,后续补充

现在看REST framework的序列化:

基本使用(对 QuerySet进行序列化)

第一种实现方式

一,普通数据库
#数据库


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

#视图

import json
from rest_framework import serializers
class Roleserializer(serializers.Serializer):
    '''序列化类'''
    id =serializers.IntegerField()
    title=serializers.CharField()                   #表字段,只有id和title,想要那个写哪个。注意一点就是要和数据库表字段保持一致

class RoleView(APIView):
    def get(self,request):
        roles=Role.object.all()   #数据库取数据,拿到QuerySet
        ser=Roleserializer(instance=roles,many=True)   #对QuerySet进行序列化,many=Ture代表有多条数据
        ret=json.dumps(ser.data,ensure_ascii=False)    #注意是ser.data,ensure_ascii=False显示中文
		'''ser已经是json字符串,再json.dumps是为了方便看'''


        return HttpResponse(ret)         #普通字符串
        #[{"id":1,"title":"医生"},{"id":2,"title":"老师}]
        '''
        role = Role.object.all().first()  # 数据库取一个数据数据,拿到QuerySet
        ser = Roleserializer(instance=role, many=False)  # 对QuerySet进行序列化,many=Fasle代表一条数据
        ret = json.dumps(ser.data, ensure_ascii=False)  # 注意是ser.data,ensure_ascii=False显示中文
        return HttpResponse(ret)  # 普通字符串
        '''

二,带有可执行字段的数据库
#数据库表

class Role(models.Model):
    title=models.CharField(max_length=32)
class UserGrope(models.Model):
    title = models.CharField(max_length=32)
class UserInfo(models.Model):
    user_type_choices=(
        (1,'普通用户'),
        (2,'VIP'),
        (3,'SVIP')
    )
    user_type=models.IntegerField(choices=user_type_choices)
    role=models.ForeignKey(Role)
    group=models.ManyToManyField('UserGrope')

#视图

#序列化类
class UserInfoserializer(serializers.Serializer):
    # usr_type=serializers.CharField(source='user_type')   #source='user_type'是对应数据库字段参数,指定了source,前面可以不对应,是显示字段
    #这样拿到的是数字
    usr_type = serializers.CharField(source='get_user_type_dispaly')  #拿到的是选项中文
    role=serializers.CharField(source='role.title')               #外键可以直接点出来
    #group=serializers.CharField(source='group.all')               #多对多拿到对象
    group=serializers.SerializerMethodField(source='group.all') #多对多自定义显示,关联函数,外键和其他也可以用这种方式
    def get_group(self,row):
        group_obj_list=row.group.all()
        ret=[]
        for item in group_obj_list:
            ret.append({"id":item.id,"title":item.title})
        return ret
#视图类
class UserView(APIView):
    def get(self,request):
        roles=UserInfo.object.all()   #数据库取数据,拿到QuerySet
        ser=UserInfoserializer(instance=roles,many=True)   #对QuerySet进行序列化,many=Ture代表有多条数据
        ret=json.dumps(ser.data,ensure_ascii=False)    #注意是ser.data,ensure_ascii=False显示中文
		'''ser已经是json字符串,再json.dumps是为了方便看'''
        return HttpResponse(ret)         #普通字符串

第二种实现方式(最常用)

#序列化类

from rest_framework import serializers
class UserInfoserializer(serializers.ModelSerializer):
    class Meta:
        model=UserInfo          #指定数据库
        #fields="_all_"         #拿到数据库所有字段信息,但只是这个数据库数据,拿不到关联数据库信息

        user_type=serializers.CharField(source='get_user_type_dispaly')
        role = serializers.CharField(source='role.title')
        group = serializers.SerializerMethodField(source='group.all')  #自定义显示
        fields=['id','user_type','role','group']
    def get_group(self,row):                       #自定义方法,可选择关联表需要显示的信息
        group_obj_list=row.all()
        ret=[]
        for item in group_obj_list:
            ret.append({"id":item.id,"title":item.title})
        return ret
#视图类
class UserView(APIView):
    def get(self,request):
        roles=UserInfo.object.all()   #数据库取数据,拿到QuerySet
        ser=UserInfoserializer(instance=roles,many=True)   #对QuerySet进行序列化,many=Ture代表有多条数据
        ret=json.dumps(ser.data,ensure_ascii=False)    #注意是ser.data,ensure_ascii=False显示中文
		'''ser已经是json字符串,再json.dumps是为了方便看'''
        return HttpResponse(ret)         #普通字符串

***补充两个方法说明:***:to_internal_value,to_representation

def to_representation(self, obj):
       """将从 Model 取出的数据 parse 给 Api"""
       return obj

   def to_internal_value(self, data):
       """将客户端传来的 json 数据 parse 给 Model"""
       return json.loads(data.encode(‘utf-8))

安全管家业务平台使用实例:

1

def mask_value(value):
    return value[:3] + '*' * 4 + value[-4:]
class CTClientProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = CTClient
        fields = ('phone', 'nickname')
        read_only_fields = ('phone',)

    def to_representation(self, instance):            #这个方法返回的结果就是返回给客户端的结果,这里的目的是把手机号中间四位隐藏掉
        ret = super().to_representation(instance)
        if ret['phone'] is not None:
            ret['phone'] = mask_value(ret['phone'])
        return ret

2

class CTClientThreatActionSerializer(serializers.ModelSerializer):
    class Meta:
        model = CTClient
        fields = ('threat_action_high', 'threat_action_medium', 'threat_action_low')
"
    def to_internal_value(self, data):                #这里是把客户端传过来的数据做转换,换成简单的"high","medium","low"。这样看上去方便一点,但又要能直接操作数据库,所以来回都要转。
        data['threat_action_high'] = data['high']
        data['threat_action_medium'] = data['medium']
        data['threat_action_low'] = data['low']
        del data['high']
        del data['medium']
        del data['low']
        return super().to_internal_value(data)

    def to_representation(self, instance):
        ret = super().to_representation(instance)
        ret['high'] = ret['threat_action_high']
        ret['medium'] = ret['threat_action_medium']
        ret['low'] = ret['threat_action_low']
        del ret['threat_action_high']
        del ret['threat_action_medium']
        del ret['threat_action_low']
        return ret

第三种实现方式:

from rest_framework import serializers
class UserInfoserializer(serializers.ModelSerializer):
    class Meta:
        model=UserInfo          #指定数据库
        fields="_all_"         #拿数据库所有的字段,也可以自己写
        #fields=['id','user_type','role','group']
        depth=1                #关联表深度查询,关联表拿到所有信息,官网建议0——10,默认为0         

你可能感兴趣的:(Django,REST,framework)