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

序列化

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)

录入一些数据

 

 

 

2)api/urls.py

from django.conf.urls import url, include

from api.views import RolesView

urlpatterns = [
  #序列化
url('(?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进行处理,many=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  如果有多个值,就需要加 many=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

from django.conf.urls import url, include

from api.views import RolesView,UserInfoView

urlpatterns = [

url('(?P<version>[v1|v2]+)/roles/', RolesView.as_view()),
url('(?P<version>[v1|v2]+)/info/', UserInfoView.as_view()),
]

(2)views.py

    '''序列化用户的信息'''
    #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)
复制代码

注意注意添加setting.py

REST_FRAMEWORK = {
    "DEFAULT_VERSIONING_CLASS":"rest_framework.versioning.URLPathVersioning",
    "ALLOWED_VERSIONS":["v1","v2"],

}

 

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

可以获取到group的url

 

5.用户请求数据验证

基本验证

(1)url.py

urlpatterns = [
url('(?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('666'),])    

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("用户提交数据验证")

提交合法/不合法数据

 

 

 

 

 

 

posted @ 2019-10-07 13:53  我的IT007  阅读(209)  评论(0编辑  收藏  举报