您的位置:首页 > 编程语言 > Go语言

Django rest framework(6)----序列化

2018-04-06 12:04 701 查看
目录

Django rest framework(1)----认证

Django rest framework(2)----权限

Django rest framework(3)----节流

Django rest framework(4)----版本

Django rest framework(5)----解析器

Django rest framework(6)----序列化

Django rest framework(7)----分页

序列化

1.继承Serializer

基本使用

(1)models.py

from django.db import models

class UserInfo(models.Model):
USER_TYPE = (
(1,'普通用户'),
(2,'VIP'),
(3,'SVIP')
)

user_type = models.IntegerField(choices=USER_TYPE)
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 UserToken(models.Model):
user = models.OneToOneField('UserInfo',on_delete=models.CASCADE)
token = models.CharField(max_length=64)

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

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


添加Role



(2)api/urls.py

urlpatterns = [
re_path('(?P<version>[v1|v2]+)/roles/', RolesView.as_view()),   #序列化
]


(3)views.py

import json

from django.shortcuts import render,HttpResponse
from rest_framework.views import APIView
from . import models

from rest_framework import serializers

#要先写一个序列化的类
class RolesSerializer(serializers.Serializer):
#Role表里面的字段id和title序列化
id = serializers.IntegerField()
title = serializers.CharField()

class RolesView(APIView):
def get(self,request,*args,**kwargs):
# 方式一:对于[obj,obj,obj]
# (Queryset)
roles = models.Role.objects.all()
# 序列化,两个参数,instance:接受Queryset(或者对象)   mangy=True表示对Queryset进行处理,mant=False表示对对象进行进行处理
ser = RolesSerializer(instance=roles,many=True)
# 转成json格式,ensure_ascii=False表示显示中文,默认为True
ret = json.dumps(ser.data,ensure_ascii=False)
return HttpResponse(ret)


(4)浏览器访问:http://127.0.0.1:8000/api/v1/roles/

可以显示后台返回的json数据



(5)方式二

class RolesView(APIView):
def get(self,request,*args,**kwargs):
# 方式一:对于[obj,obj,obj]
# (Queryset)
# roles = models.Role.objects.all()
# 序列化,两个参数,instance:Queryset  如果有多个值,就需要加 mangy=True
# ser = RolesSerializer(instance=roles,many=True)
# 转成json格式,ensure_ascii=False表示显示中文,默认为True
# ret = json.dumps(ser.data,ensure_ascii=False)

# 方式二:
role = models.Role.objects.all().first()
ser = RolesSerializer(instance=role, many=False)
ret = json.dumps(ser.data, ensure_ascii=False)
return HttpResponse(ret)


只获取一个



进阶使用

(1)urls.py

添加一个info

urlpatterns = [
re_path('(?P<version>[v1|v2]+)/roles/', RolesView.as_view()),   #序列化
re_path('(?P<version>[v1|v2]+)/info/', UserInfoView.as_view()),   #序列化
]


(2)views.py

class UserInfoSerializer(serializers.Serializer):
'''序列化用户的信息'''
#user_type是choices(1,2,3),显示全称的方法用source
type = serializers.CharField(source="get_user_type_display")
username = serializers.CharField()
password = serializers.CharField()
#group.title:组的名字
group = serializers.CharField(source="group.title")
#SerializerMethodField(),表示自定义显示
#然后写一个自定义的方法
rls = serializers.SerializerMethodField()

def get_rls(self,row):
#获取用户所有的角色
role_obj_list = row.roles.all()
ret = []
#获取角色的id和名字
#以字典的键值对方式显示
for item in role_obj_list:
ret.append({"id":item.id,"title":item.title})
return ret

class UserInfoView(APIView):
'''用户的信息'''
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)


自定义方法



(3)浏览器访问:http://127.0.0.1:8000/api/v1/info/



2.继承 ModelSerializer

把上面的UserInfoSerializer改成继承ModelSerializer的用法

# class UserInfoSerializer(serializers.Serializer):
#     '''序列化用户的信息'''
#     #user_type是choices(1,2,3),显示全称的方法用source
#     type = serializers.CharField(source="get_user_type_display")
#     username = serializers.CharField()
#     password = serializers.CharField()
#     #group.title:组的名字
#     group = serializers.CharField(source="group.title")
#     #SerializerMethodField(),表示自定义显示
#     #然后写一个自定义的方法
#     rls = serializers.SerializerMethodField()
#
#     def get_rls(self,row):
#         #获取用户所有的角色
#         role_obj_list = row.roles.all()
#         ret = []
#         #获取角色的id和名字
#         #以字典的键值对方式显示
#         for item in role_obj_list:
#             ret.append({"id":item.id,"title":item.title})
#         return ret

class UserInfoSerializer(serializers.ModelSerializer):
type = serializers.CharField(source="get_user_type_display")
group = serializers.CharField(source="group.title")
rls = serializers.SerializerMethodField()

def get_rls(self, row):
# 获取用户所有的角色
role_obj_list = row.roles.all()
ret = []
# 获取角色的id和名字
# 以字典的键值对方式显示
for item in role_obj_list:
ret.append({"id": item.id, "title": item.title})
return ret

class Meta:
model = models.UserInfo
fields = ['id','username','password','type','group','rls']

class UserInfoView(APIView):
'''用户的信息'''
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)


结果一模一样



3.自动序列化连表(depth)

继续优化上面的代码,用depth更简单方便

class UserInfoSerializer(serializers.ModelSerializer):
class Meta:
model = models.UserInfo
#fields = "__all__"
fields = ['id','username','password','group','roles']
#表示连表的深度
depth = 1

class UserInfoView(APIView):
'''用户的信息'''
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)


访问:http://127.0.0.1:8000/api/v1/info/



4.生成url

url.py

urlpatterns = [
re_path('(?P<version>[v1|v2]+)/group/(?P<pk>\d+)/', GroupView.as_view(),name = 'gp')    #序列化生成url
]


views.py

class UserInfoSerializer(serializers.ModelSerializer):
group = serializers.HyperlinkedIdentityField(view_name='gp',lookup_field='group_id',lookup_url_kwarg='pk')
class Meta:
model = models.UserInfo
#fields = "__all__"
fields = ['id','username','password','group','roles']
#表示连表的深度
depth = 0

class UserInfoView(APIView):
'''用户的信息'''
def get(self,request,*args,**kwargs):
users = models.UserInfo.objects.all()
#这里必须要传参数context={'request':request}
ser = UserInfoSerializer(instance=users,many=True,context={'request':request})
ret = json.dumps(ser.data,ensure_ascii=False)
return HttpResponse(ret)

class GroupSerializer(serializers.ModelSerializer):
class Meta:
model = models.UserGroup
fields = "__all__"

class GroupView(APIView):
def get(self,request,*args,**kwargs):
pk = kwargs.get('pk')
obj = models.UserGroup.objects.filter(pk=pk).first()

ser = GroupSerializer(instance=obj,many=False)
ret = json.dumps(ser.data,ensure_ascii=False)
return HttpResponse(ret)


访问:http://127.0.0.1:8000/api/v1/info/

可以获取到group的url



5.用户请求数据验证

基本验证

(1)url.py

urlpatterns = [
re_path('(?P<version>[v1|v2]+)/usergroup/', UserGroupView.as_view(),)    #序列化做验证
]


(2)views.py

class UserGroupSerializer(serializers.Serializer):
title = serializers.CharField()

class UserGroupView(APIView):
def post(self,request,*args, **kwargs):
ser = UserGroupSerializer(data=request.data)
if ser.is_valid():
print(ser.validated_data['title'])
else:
print(ser.errors)

return HttpResponse("用户提交数据验证")


用postman发送正确的数据,后台可以拿到





发送空数据,会自动验证数据的合法性





自定义验证规则

views.py

添加一个自定义验证

#自定义验证规则
class GroupValidation(object):
def __init__(self,base):
self.base = base

def __call__(self, value):
if not value.startswith(self.base):
message = "标题必须以%s为开头"%self.base
raise serializers.ValidationError(message)

class UserGroupSerializer(serializers.Serializer):
title = serializers.CharField(validators=[GroupValidation('以我开头'),])

class UserGroupView(APIView):
def post(self,request,*args, **kwargs):
ser = UserGroupSerializer(data=request.data)
if ser.is_valid():
print(ser.validated_data['title'])
else:
print(ser.errors)

return HttpResponse("用户提交数据验证")


提交不合法的数据



后台报错



提交正确的数据



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: