zoukankan      html  css  js  c++  java
  • 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('.....')
  • 相关阅读:
    二分查找思路以及可能出现情况对应解决办法
    多线程知识点大纲
    服务器consul启动方法
    大白话带你认识 ZooKeeper !重要概念一网打尽!
    「Netty实战 02」手把手教你实现自己的第一个 Netty 应用!新手也能搞懂!
    从 BIO、NIO 聊到 Netty,最后还要实现个 RPC 框架!
    什么是P问题、NP问题和NPC问题
    期刊汇总
    Typora 使用
    TCA 复习
  • 原文地址:https://www.cnblogs.com/1a2a/p/8428390.html
Copyright © 2011-2022 走看看