解析器是对请求体数据进行解析
序列化有两个用处:
1.对 QuerySet进行序列化(json不能序列化QuerySet类型)
2.对请求数据进行校验
Django也自带了一个对QuerySet进行序列化的方法,后续补充
现在看REST framework
的序列化:
一,普通数据库
#数据库
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