• Django Rest Framework进阶二


    一、版本

    版本控制:当程序越来越大,后期需要再加入一些功能或者进行二次开发时就需要加上版本号了。

    之前我们在没有接触rest_framework之前一般是以下这种方式来实现的

    class UserView(APIView):
        def get(self,request,*args,**kwargs):
            version = request.query_params.get('version')
            print(version)
            if version=='v1':
                #如果版本是v1
                ret = {
                    'code':111,
                    'msg':'版本一的内容'
                }
    
            elif version=='v2':
                # 如果是v2
                ret = {
                    'code': 112,
                    'msg': '版本二的内容'
                }
            else:
                ret = {
                    'code': 0,
                    'msg': '不支持其他版本'
                }
            return Response(ret) 

    现在我们可以用rest_framework来实现,主要有两种方式

    方式一:基于url

     #基于url传参的形式
         versioning_class = QueryParameterVersioning
        #http://127.0.0.1:8080/api/users/?version=v2
        
    #基于url的形式
      versioning_class = URLPathVersioning
      #http://127.0.0.1:8080/api/v1/users/

    具体操作

    REST_FRAMEWORK = {
         'DEFAULT_VERSION': 'v1',  #默认的版本
         'ALLOWED_VERSIONS': ['v1','v2'],  #允许的版本
         'VERSION_PARAM': 'version',
     }
    配置
    1 from django.conf.urls import url,include
    2 from django.contrib import admin
    3 
    4 
    5 urlpatterns = [
    6     url(r'^admin/', admin.site.urls),
    7     url(r'^api/(?P<version>[v1|v2]+)/', include('api.urls'), name='users-list'),
    8 ]
    urls.py
    1 from api import views
    2 urlpatterns = [
    3     # url(r'^users/', views.UserView.as_view()),
    4     url(r'^users/', views.UserView1.as_view()),
    5 
    6 ]
    urls
    class UserView1(APIView):
        #基于url传参的形式
        # versioning_class = QueryParameterVersioning
        #http://127.0.0.1:8080/api/users/?version=v2
    
        #基于url的形式
        #http://127.0.0.1:8080/api/v1/users/
        versioning_class = URLPathVersioning
        def get(self,request,*args,**kwargs):
            # self.dispatch
            print(request.version)  #打印的是版本
            print(request.versioning_scheme)  #打印的是对象
            if request.version=='v2':
                return Response('我是版本二')
            elif request.version=='v1':
                return Response('我是版本一')
            else:
                return Response('...')
    
    views.py
    view.py

    注意:配置

    REST_FRAMEWORK = {
                    'VERSION_PARAM':'version',
                    'DEFAULT_VERSION':'v1',
                    'ALLOWED_VERSIONS':['v1','v2'],
                    # 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.HostNameVersioning" 
               #如果加上这个配置就不用versioning_class = QueryParameterVersioning这样在指定了,
               'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.URLPathVersioning" } 

    补充:restful提供的反向生成(http://127.0.0.1:8080/api/v1/users/)

    #urls.py 
    #分发路由
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^api/(?P<version>[v1|v2]+)/', include('api.urls')),
    ]
    
    #api.urls.py
    urlpatterns = [
        url(r'^users/', views.UserView1.as_view(), name='users-list'),
    ]
    
    #views.py 
    导入类
    from rest_framework.reverse import reverse
    url = request.versioning_scheme.reverse(viewname='users-list',request=request)
            print(url)
    
    restfoamework反向解析
    restfoamework反向解析

    我们用django实现的,当前版本不一样的时候可以用这种方式。

    from django.urls import reverse
            url = reverse(viewname='users-list',kwargs={'version':'v2'}) #指定的是v2就是v2,当你路径中输入v1的时候还是v2的路径
            print(url) #/api/v2/users/
    

    方式二:基于子域名传参

    #分发url
                urlpatterns = [
                    #url(r'^admin/', admin.site.urls),
                    url(r'^api/', include('api.urls')),
                ]
    
                urlpatterns = [
                    url(r'^users/', views.UsersView.as_view(),name='u'),
                ]
                
                
                class UsersView(APIView):
                    
                    def get(self,request,*args,**kwargs):
                        self.dispatch
                        print(request.version) # QueryParameterVersioning().detemiin_version()
                        print(request.versioning_scheme) # QueryParameterVersioning()
    
                
                REST_FRAMEWORK = {
                    'VERSION_PARAM':'version',
                    'DEFAULT_VERSION':'v1',
                    'ALLOWED_VERSIONS':['v1','v2'],
                    'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.HostNameVersioning"
                }
                
                # C:WindowsSystem32driversetc
                # vim /etc/hosts
                127.0.0.1    v1.luffy.com
                127.0.0.1    v2.luffy.com
                
                #配置ALLOWED_HOSTS = ['*']
    
    基于子域名传参
    基于子域名传参

    二、解析器

    用处:request.data取值的时候才会用到

    对请求的数据进行解析:是针对请求体进行解析的。表示服务器可以解析的数据格式的种类

    django中的发送请求

    #如果是这样的格式发送的数据,在POST里面有值
    Content-Type: application/url-encoding.....
        request.body
        request.POST
        
    #如果是发送的json的格式,在POST里面是没有值的,在body里面有值,可通过decode,然后loads取值        
    Content-Type: application/json.....
        request.body
        request.POST
    

    为了这种情况下每次都要decode,loads,显得麻烦,所以才有的解析器。弥补了django的缺点

    客户端:
                Content-Type: application/json
                '{"name":"alex","age":123}'
            
            服务端接收:
                读取客户端发送的Content-Type的值 application/json
                
                parser_classes = [JSONParser,FormParser]  #表示服务器可以解析的数据格式的种类
                media_type_list = ['application/json','application/x-www-form-urlencoded']
            
                如果客户端的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',
                        ]
                    }
                    
                    class UserView(APIView):
                        def get(self,request,*args,**kwargs):
                            return Response('ok')
                        def post(self,request,*args,**kwargs):
                            print(request.data)  #以后取值就在这里面去取值
                            return Response('...')
    具体讲解

    上传文件

    1 from django.conf.urls import url, include
    2 from web.views import TestView
    3 
    4 urlpatterns = [
    5     url(r'test/(?P<filename>[^/]+)', TestView.as_view(), name='test'),
    6 ]
    urls
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from rest_framework.request import Request
    from rest_framework.parsers import FileUploadParser
    
    
    class TestView(APIView):
        parser_classes = [FileUploadParser, ]
    
        def post(self, request, filename, *args, **kwargs):
            print(filename)
            print(request.content_type)
    
            # 获取请求的值,并使用对应的JSONParser进行处理
            print(request.data)
            # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
            print(request.POST)
            print(request.FILES)
            return Response('POST请求,响应内容')
    
        def put(self, request, *args, **kwargs):
            return Response('PUT请求,响应内容')
    
    views.py
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <form action="http://127.0.0.1:8000/test/f1.numbers" method="post" enctype="multipart/form-data">
        <input type="text" name="user" />
        <input type="file" name="img">
    
        <input type="submit" value="提交">
    
    </form>
    </body>
    </html>
    
    upload.html
    upload.html

    全局使用

    REST_FRAMEWORK = {
        'DEFAULT_PARSER_CLASSES':[
            'rest_framework.parsers.JSONParser'
            'rest_framework.parsers.FormParser'
            'rest_framework.parsers.MultiPartParser'
        ]
    
    }
    settings.py
  • 相关阅读:
    关于开发 Web AI 的思考(kendryte K210)
    怪不得我说,这几个月的代码数据都跑哪里去了....
    在 Android 上使用蓝牙作为主机进行一对多从机传输数据的实测,理论 5
    写了一下 micropython 的文件系统单元测试
    mark 自己未来要写一下,蓝牙主机一对多从机和 K210 的网络通信优化过程。
    VUE实现Studio管理后台(五):手风琴式折叠组件(Accordion)
    VUE实现Studio管理后台(四):状态模式实现窗口停靠,灵动、自由
    VUE实现Studio管理后台(三):支持多语言国际化(vue-i18n)
    VUE实现Studio管理后台(二):Slot实现选项卡tab切换效果,可自由填装内容
    VUE实现Studio管理后台(一):鼠标拖放改变窗口大小
  • 原文地址:https://www.cnblogs.com/moning/p/8432994.html
Copyright © 2020-2023  润新知