Django REST framework之版本,解释器,序列化

1 版本

2 解释器

3.序列化

1 版本

通过?后面传版本号有两种方法:

方法一

from django.shortcuts import render
from rest_framework.views import  APIView
from rest_framework.response import Response
from  rest_framework.authentication import BasicAuthentication
from rest_framework.versioning import QueryParameterVersioning,URLPathVersioning,HostNameVersioning
from rest_framework.renderers import BrowsableAPIRenderer,JSONRenderer

# Create your views here.
class UserView(APIView):
    #版本号通过?后面传参数
    def get(self,request,*args,**kwargs):
        print('11111',request.version)
        version=request.query_params.get('version')
        if version=="v1":
            ret={
                "name":"Frank"
            }
        elif version=="v2":
            ret={
                "name":"Tom"
            }
        else:
            ret='错误信息'
        return  Response(ret)

方法二:

versioning_class = QueryParameterVersioning#用这个的话,可以使用request.version来获取值

    def get(self, request, *args, **kwargs):
        print('11111', request.version)

        if request.version == "v1":
            ret = {
                "name": "Frank5555"
            }
        elif request.version == "v2":
            ret = {
                "name": "Tom"
            }
        else:
            ret = '错误信息'
        return Response(ret)

把url放在里面:

 #版本号放在URL里面
    # versioning_class = URLPathVersioning
    #
    # def get(self, request, *args, **kwargs):
    #     print('11111', request.version)
    #     from django.urls import reverse
    #     url=reverse(viewname="u",kwargs={"version":'v1'})#django生成的URl需要拼接
    #     # url=request.versioning_scheme.reverse(viewname='u',request=request)#反向生成URl,这个URL不需要拼接。
    #     print(url)
    #     if request.version == "v1":
    #         ret = {
    #             "name": "Frank5555"
    #         }
    #     elif request.version == "v2":
    #         ret = {
    #             "name": "Tom"
    #         }
    #     else:
    #         ret = '错误信息'
    #     return Response(ret)

子域名版本:

  versioning_class=HostNameVersioning
     def get(self, request, *args, **kwargs):
        # print('11111', request.version)
        # print('222',request.versioning_scheme)

        if request.version == "v1":
            ret = {
                "name": "Frank5555"
            }
        elif request.version == "v2":
            ret = {
                "name": "Tom"
            }
        else:
            ret = '错误信息'
        return Response(ret)

上面的设置可以看成时在视图里面设置的。

也可以在全局设置:(只能使用一种)

REST_FRAMEWORK = {
                'VERSION_PARAM':'version',
                'DEFAULT_VERSION':'v1',
                'ALLOWED_VERSIONS':['v1','v2'],
                #'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.HostNameVersioning"
                'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.URLPathVersioning"
            }

 

 

2 解释器

文字解释:

请求的数据进行解析:请求体进行解析。表示服务端可以解析的数据格式的种类。
        
            Content-Type: application/url-encoding.....
            request.body
            request.POST
            
            Content-Type: application/json.....
            request.body
            request.POST#里面没有数据
        
        客户端:
            Content-Type: application/json
            '{"name":"alex","age":123}'
        
        服务端接收:
            读取客户端发送的Content-Type的值 application/json
            
            parser_classes = [JSONParser,]
        
            如果客户端的Content-Type的值和 application/json 匹配:JSONParser处理数据
            如果客户端的Content-Type的值和 application/x-www-form-urlencoded 匹配:FormParser处理数据
        
        
        配置:
            单视图:
            class UsersView(APIView):
                parser_classes = [JSONParser,]
                
            全局配置:
                REST_FRAMEWORK = {
                    'VERSION_PARAM':'version',
                    'DEFAULT_VERSION':'v1',
                    'ALLOWED_VERSIONS':['v1','v2'],
                    # 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.HostNameVersioning"
                    'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.URLPathVersioning",
                    'DEFAULT_PARSER_CLASSES':[
                        'rest_framework.parsers.JSONParser',
                        'rest_framework.parsers.FormParser',
                    ]
                }

 

     

from django.shortcuts import render

# Create your views here.
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import  BasicAuthentication
from rest_framework.versioning import QueryParameterVersioning,URLPathVersioning,HostNameVersioning
from rest_framework.parsers import JSONParser,FormParser
class UserView(APIView):

    def get(self,request,*args,**kwargs):
        print('生活如此美好')
        return  Response(">>>>>fuck")
    def post(self,request,*args,**kwargs):
        #parser_classes = [JSONParser, ]这是局部的

        #application/json
        print('json',request._request.body)#里面放的时Json数据是b"xxxxx"
        print('json',request._request.POST)#里面没有数据
        print('json',request.data)
        #www-form-url-encode
        print('body',request._request.body)#字节的形式b'k1=v1&k2=v2'
        print('post',request._request.POST)# <QueryDict: {'k1': ['v1'], 'k2': ['v2']}>
        print('encode',request.data)
        print(request.POST)
        return  Response('.......')

 

3.序列化

  rest framework序列化+From验证

   序列化:

          对象=》字符串  序列化

          字符串=》对象    反序列化

  目的:

     解决QuerySet序列化问题

用到了路由分发:

"""demo URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url,include
from django.contrib import admin


urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # url(r'^app01/(?P<version>[v1|v2]+)/', include('app01.urls')),
    url(r'^app01/', include('app01.urls')),
    url(r'^app02/', include('app02.urls')),
    url(r'^app03/', include('app03.urls')),
    url(r'^app05/', include('app05.urls')),
]

每个app里面的路由都是大同小异:

from django.conf.urls import url

from . import  views

urlpatterns = [

    url(r'^user/', views.UserView.as_view(),name='u'),

]

 

     a.基本操作:        

class UsersSerializer(serializers.Serializer):
            name = serializers.CharField()
            pwd = serializers.CharField()
            
                        
 class UsersView(APIView):
           def get(self,request,*args,**kwargs):
                self.dispatch
                # 方式一:
                # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title")
                # return Response(user_list)

                # 方式二之多对象
                # user_list = models.UserInfo.objects.all()
                # ser = UsersSerializer(instance=user_list,many=True)
                # return Response(ser.data)

                # 方式二之单对象
                user = models.UserInfo.objects.all().first()
                ser = UsersSerializer(instance=user, many=False)
                return Response(ser.data)

b.跨表操作:

class UsersSerializer(serializers.Serializer):
                      name = serializers.CharField()
                      pwd = serializers.CharField()
                      group_id = serializers.CharField()
                      xxxx = serializers.CharField(source="group.title")
                      x1 = serializers.CharField(source="group.mu.name")

                class UsersView(APIView):
                    def get(self,request,*args,**kwargs):
                        self.dispatch
                        # 方式一:
                        # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title")
                        # return Response(user_list)

                        # 方式二之多对象
                        user_list = models.UserInfo.objects.all()
                        ser = UsersSerializer(instance=user_list,many=True)
                        return Response(ser.data)

c.复杂多对多操作(主要是多对多的显示)

方法一:


from django.shortcuts import render
from rest_framework.views import APIView

from rest_framework.response import Response
from rest_framework.authentication import BasicAuthentication
from rest_framework.versioning import QueryParameterVersioning
from rest_framework import serializers
from rest_framework.request import Request
from . import models


class
MyCharField(serializers.CharField): def to_representation(self, value): print(value) data_list=[] for row in value: data_list.append(row.name) return data_list class UsersSerializer(serializers.Serializer): name = serializers.CharField() pwd = serializers.CharField() # group_id=serializers.CharField() # xxxx=serializers.CharField(source="group.title") # x1=serializers.CharField(source="group.mu.name") x2=MyCharField(source="roles.all")#多对多建立方法就是更改显示的方式
class UserView(APIView):
    def get(self, request, *args, **kwargs):
        user_list = models.UserInfo.objects.all().first()
        ser = UsersSerializer(instance=user_list, many=False)

        return Response(ser.data)

方法二:

class MyCharField(serializers.CharField):
    def to_representation(self, value):
        return  {'id':value.pk,'name':value.name}
class UsersSerializer(serializers.Serializer):
    name = serializers.CharField()
    pwd = serializers.CharField()
    # group_id=serializers.CharField()
    # xxxx=serializers.CharField(source="group.title")
    # x1=serializers.CharField(source="group.mu.name")
    # x2=MyCharField(source="roles.all")#多对多建立方法就是更改显示的方式
    x2=serializers.ListField(child=MyCharField(),source="roles.all")

方法三:(推荐使用这个方法因为可以自己修改和加约束条件)

class UsersSerializer(serializers.Serializer):
    name = serializers.CharField()
    pwd = serializers.CharField()
    # group_id=serializers.CharField()
    # xxxx=serializers.CharField(source="group.title")
    # x1=serializers.CharField(source="group.mu.name")
    # x2=MyCharField(source="roles.all")#多对多建立方法就是更改显示的方式
    # x2=serializers.ListField(child=MyCharField(),source="roles.all")
    x2=serializers.SerializerMethodField()
    def get_x2(self,obj):
        obj.roles.all()
        role_list=obj.roles.filter(id__gt=1)
        data_list=[]
        for row in role_list:
            data_list.append({'pk':row.pk,'name':row.name})
        return  data_list
以上三种都是使用相同的视图:

d.生成Modell时:

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

class UserView(APIView):
    def get(self, request, *args, **kwargs):
        user_list = models.UserInfo.objects.all().all()
        ser = UsersSerializer(instance=user_list, many=True)

        return Response(ser.data)

e.生成Ulr时:

class UsersSerializer(serializers.ModelSerializer):
    group=serializers.HyperlinkedIdentityField(view_name='detail')
    class Meta:
        model=models.UserInfo
        # fields="__all__"
        fields=['name','pwd','group']
        depth=1


class UserView(APIView):
    def get(self, request, *args, **kwargs):
        user_list = models.UserInfo.objects.all()
        ser = UsersSerializer(instance=user_list, many=True,context={'request':request})

        return Response(ser.data)

url为

from django.conf.urls import url

from . import  views

urlpatterns = [

    url(r'^user/', views.UserView.as_view(),name='u'),
    url(r'^xxxx/(?P<pk>\d+)', views.UserView.as_view(),name='detail'),
    url(r'^xxxx/(?P<pk>\d+)', views.UserView.as_view(),name='detail'),
    url(r'^xxxx/(?P<pk>\d+)', views.UserView.as_view(),name='detail'),
]

f生成全局URL时:

class UsersSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model=models.UserInfo
        fields="__all__"
        # fields=['name','pwd','group']
        # depth=1


class UserView(APIView):
    def get(self, request, *args, **kwargs):
        user_list = models.UserInfo.objects.all()
        ser = UsersSerializer(instance=user_list, many=True,context={'request':request})

        return Response(ser.data)

它的url:

from django.conf.urls import url

from . import  views

urlpatterns = [

    url(r'^user/', views.UserView.as_view(),name='u'),
    # url(r'^xxxx/(?P<pk>\d+)', views.UserView.as_view(),name='detail'),
    # url(r'^xxxx/(?P<pk>\d+)', views.UserView.as_view(),name='detail'),
    # url(r'^xxxx/(?P<pk>\d+)', views.UserView.as_view(),name='detail'),
    url(r'^xxxx/(?P<pk>\d+)', views.UserView.as_view(),name='userinfo-detail'),
    url(r'^xxxx/(?P<pk>\d+)', views.UserView.as_view(),name='group-detail'),
    url(r'^xxxx/(?P<pk>\d+)', views.UserView.as_view(),name='role-detail'),

]

数据验证有两种方式:

a.

class PasswordValidator(object):
    def __init__(self,base):
        self.base=base
    def __call__(self, value):
        if value !=self.base:
            message='用户输入的值必须是%s'%self.base
            raise  serializers.ValidationError(message)
    def set_context(self,serializer_field):
        pass
class UserSeializer(serializers.Serializer):
    name=serializers.CharField(min_length=6)
    pwd=serializers.CharField(error_messages={'required':'密码不能为空'},validators=[PasswordValidator('666')])


class UserView(APIView):
    def get(self,request,*args,**kwargs):
        user_list=models.UserInfo.objects.all()
        ser=UserSeializer(instance=user_list,many=True,context={'request':request})
    def post(self,request,*args,**kwargs):
        ser=UserSeializer(data=request.data)
        if ser.is_valid():

            print(ser.validated_data)
        else:
            print(ser.errors)
        return  Response('.....')

b.

class PasswordValidator(object):
    def __init__(self,base):
        self.base=base
    def __call__(self, value):
        if value !=self.base:
            message='用户输入的值必须是%s'%self.base
            raise  serializers.ValidationError(message)
    def set_context(self,serializer_field):
        pass
class UserSeializer(serializers.ModelSerializer):
    class Meta:
        model=models.UserInfo
        fields="__all__"
        extra_kwargs={
            'name':{'min_length':6},
            'pwd':{'validators':[PasswordValidator(666),]}

        }


class UserView(APIView):
    def get(self,request,*args,**kwargs):
        user_list=models.UserInfo.objects.all()
        ser=UserSeializer(instance=user_list,many=True,context={'request':request})
    def post(self,request,*args,**kwargs):
        ser=UserSeializer(data=request.data)
        if ser.is_valid():

            print(ser.validated_data)
        else:
            print(ser.errors)
        return  Response('.....')

 

posted on 2018-02-07 20:46  黎明NB  阅读(215)  评论(0编辑  收藏  举报

导航