DRF——请求的封装与版本管理

django restframework

  • 快速上手
  • 请求的封装
  • 版本管理
  • 认证
  • 权限
  • 限流
  • 序列化
  • 视图
  • 条件搜索
  • 分页
  • 路由
  • 解析器

1. 快速上手

  • 安装

    pip install djangorestframework==3.12.4
    
    版本要求:djangorestframework==3.12.4
    	Python (3.5, 3.6, 3.7, 3.8, 3.9)
    	Django (2.2, 3.0, 3.1)
        
    版本要求:djangorestframework==3.11.2
    	Python (3.5, 3.6, 3.7, 3.8)
    	Django (1.11, 2.0, 2.1, 2.2, 3.0)
    
  • 配置,在settings.py中添加配置

    INSTALLED_APPS = [
        ...
        # 注册rest_framework(drf)
        'rest_framework',
    ]
    
    # drf相关配置以后编写在这里 
    REST_FRAMEWORK = {
       
    }
    
  • URL和视图

    # urls.py
    
    from django.urls import path
    from app01 import views
    
    urlpatterns = [
        path('users/', views.UserView.as_view()),
    ]
    
    # views.py
    from rest_framework.views import APIView
    from rest_framework.response import Response
    
    
    class UserView(APIView):
        def get(self, request, *args, **kwargs):
            return Response({"code": 1000, "data": "xxx"})
    
        def post(self, request, *args, **kwargs):
            return Response({"code": 1000, "data": "xxx"})
    

其实drf框架是在django基础进行的扩展,所以上述执行过得底层实现流程(同django的CBV):
在这里插入图片描述

drf中重写了 as_viewdispatch方法,其实就是在原来django的功能基础上添加了一些功能,例如:

  • as_view,免除了csrf 验证,一般前后端分离不会使用csrf token认证(后期会使用jwt认证)。
  • dispatch,内部添加了 版本处理、认证、权限、访问频率限制等诸多功能(后期逐一讲解)。

在前后端不分离项目中要解决post,put,delete的crsf问题时:通常会在表单中加入{% csrf_token %}

在这里插入图片描述

而如果是在前后端分离项目中就不可行了,此时就需要csrf_exempt装饰器:

在这里插入图片描述

2. 请求数据的封装

drf的request是 原来django的request与认证,解析等对象一起封装后的对象。

以前我们通过django开发项目时,视图中的request是 django.core.handlers.wsgi.WSGIRequest 类的对象,其中包含了请求相关的所有数据。

# Django FBV
def index(request):
	request.method
	request.POST
	request.GET
	request.body

# Django CBV
from django.views import View
class UserView(View):
	def get(self,request):
        request.method
        request.POST
        request.GET
        request.body

而在使用drf框架时,视图中的request是rest_framework.request.Request类的对象,其是又对django的request进行了一次封装,包含了除django原request对象以外,还包含其他后期会使用的其他对象。

from rest_framework.views import APIView
from rest_framework.response import Response


class UserView(APIView):
    def get(self, request, *args, **kwargs):
        # request,不再是django中的request,而是又被封装了一层,内部包含:django的request、认证、解析器等。
        return Response({"code": 1000, "data": "xxx"})

    def post(self, request, *args, **kwargs):
        return Response({"code": 1000, "data": "xxx"})

对象 = (request, 其他数据)
# rest_framework.request.Request 类

class Request:
    """
    Wrapper allowing to enhance a standard `HttpRequest` instance.
    Kwargs:
        - request(HttpRequest). The original request instance. (django中的request)
        - parsers(list/tuple). The parsers to use for parsing the
          request content.
        - authenticators(list/tuple). The authenticators used to try
          authenticating the request's user.
    """

    def __init__(self, request, parsers=None, authenticators=None,negotiator=None, parser_context=None):
    	self._request = request
        self.parsers = parsers or ()
        self.authenticators = authenticators or ()
        ...
	
    @property
    def query_params(self):
        """
        More semantically correct name for request.GET.
        """
        return self._request.GET

    @property
    def data(self):
        if not _hasattr(self, '_full_data'):
            self._load_data_and_files()
        return self._full_data
    
	def __getattr__(self, attr):
        try:
            return getattr(self._request, attr) # self._request.method
        except AttributeError:
            return self.__getattribute__(attr)

所以,在使用drf框架开发时,视图中的request对象与原来的有些不同,例如:

from rest_framework.views import APIView
from rest_framework.response import Response
from django.views import View
from rest_framework.request import Request


class UserView(APIView):
    def get(self, request, *args, **kwargs):
        
        # 通过对象的嵌套直接找到原request,读取相关值
        request._request.method
        request._request.GET
        request._request.POST
        request._request.body
        
        # 举例:
        	content-type: url-form-encoded
        	v1=123&v2=456&v3=999
            django一旦读取到这个请求头之后,就会按照 {"v1":123,"v2":456,"v3":999}
            
            content-type: application/json
            {"v1":123,"v2":456}
            request._request.POST
            request._request.body
        
        # 直接读取新request对象中的值,一般此处会对原始的数据进行一些处理,方便开发者在视图中使用。
        request.query_params  # 内部本质上就是 request._request.GET
        request.data # 内部读取请求体中的数据,并进行处理,例如:请求者发来JSON格式,他的内部会对json字符串进行反序列化。
        
        # 通过 __getattr__ 去访问 request._request 中的值
        request.method
        
        

底层源码实现:

在这里插入图片描述

3. 版本管理

在restful规范中要去,后端的API中需要体现版本。

drf框架中支持5种版本的设置。(重点是前两种:参数传递,URL路径传递)

3.1 URL的GET参数传递(*)

在这里插入图片描述

# settings.py

REST_FRAMEWORK = {
    "VERSION_PARAM": "v",
    "DEFAULT_VERSION": "v1",
    "ALLOWED_VERSIONS": ["v1", "v2", "v3"],
    "DEFAULT_VERSIONING_CLASS":"rest_framework.versioning.QueryParameterVersioning"
}

源码执行流程:

在这里插入图片描述

3.2 URL路径传递(*)

在这里插入图片描述

3.3 请求头传递

在这里插入图片描述

3.4 二级域名传递

在这里插入图片描述

在使用二级域名这种模式时需要先做两个配置:

  • 域名需解析至IP,本地可以在hosts文件中添加
    在这里插入图片描述

    127.0.0.1       v1.wupeiqi.com
    127.0.0.1       v2.wupeiqi.com
    
  • 在django的settings.py配置文件中添加允许域名访问

    ALLOWED_HOSTS = ["*"]
    
3.5 路由的namespace传递

在这里插入图片描述

以上就是drf中支持的5种版本管理的类的使用和配置。

全局配置

上述示例中,如果想要应用某种 版本 的形式,需要在每个视图类中定义类变量:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.versioning import QueryParameterVersioning


class UserView(APIView):
    versioning_class = QueryParameterVersioning
    ...

如果你项目比较大,需要些很多的视图类,在每一个类中都写一遍会比较麻烦,所有drf中也支持了全局配置。

# settings.py

REST_FRAMEWORK = {
    "DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.QueryParameterVersioning",  # 处理版本的类的路径
    "VERSION_PARAM": "version",  # URL参数传参时的key,例如:xxxx?version=v1
    "ALLOWED_VERSIONS": ["v1", "v2", "v3"],  # 限制支持的版本,None表示无限制
    "DEFAULT_VERSION": "v1",  # 默认版本
}

在这里插入图片描述

底层源码实现

在这里插入图片描述

反向生成URL

使用drf是可以通过request.versioning_scheme.reverse(viewname, args, kwargs, request)来反向生成URL

在每个版本处理的类中还定义了reverse方法,他是用来反向生成URL并携带相关的的版本信息用的,例如:

在这里插入图片描述

在这里插入图片描述

小结

以后使用drf开发后端API接口时:

  1. 创建django程序
  2. 安装drf框架
  3. 创建一个app专门来处理用户的请求
  4. 注册APP
  5. 设置版本
  6. 编写视图类

若有错误与不足请指出,关注DPT一起进步吧!!!

  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叫我DPT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值