DRF的请求响应组件

下面我们介绍DRF的请求响应组件,主要包括三种,即请求模块,响应模块和解析模块.另外还有两个常用的相关模块,即渲染模块和异常模块.我们分别从模块的使用和源码分析来介绍,这里我们安装的DRF版本是最原始的0.1.0,所以下面的源码都是以这个版本为准的.

请求模块(request)

概念

drf的请求模块其实是在wsgi的request基础上再次封装,wsgi中的request模块是作为drf里面新的request模块的一个属性,名为_request,并对其完全兼容,且对于数据的解析鼓风机啊规范化,所有url拼接的参数都存放在了query_params中,而所有的数据包数据都被解析并存放在了data中,且query_paramsdata都是QueryDict类型,可以通过后缀.dict()来转化为原生的dict类型.

drf的request从根本上来说是基于CBV的一种结构,并在其上面做了各种扩展,而CBV源码中最关键的就是as_view方法和dispatch方法,drf中同样有.

request源码简单分析

# /rest_framework/views.py/APIView(View)
# 上面地址可以通过下面的导入语句,然后按住ctrl+鼠标左键点击APIView进入
from rest_framework.views import APIView
# 121行到144行,是as_view的源码,一方面,这个源码的父类是继承于View,也就是wsgi最原始的View,所以有些方法是直接用的View中的.
# 我们在as_view的源码中,只需要注意两点, @classmethod
def as_view(cls, **initkwargs):
view = super().as_view(**initkwargs) # 该行是直接调用的其父类,也就是wsgi的View类来实现生成一个新的view,相当于重写了as_view方法,其主体逻辑还是View里面的as_view()
return csrf_exempt(view) # 这里返回的是局部禁用的csrf认证的view视图函数,csrf_exempt就是可以局部禁用csrf的方法 # 484到511行,是DRF重写的dispatch(),其内部还是原本View内部dispatch方法,不过另外封装了两个功能,如下
def dispatch(self, request, *args, **kwargs):
self.args = args
self.kwargs = kwargs
request = self.initialize_request(request, *args, **kwargs) # 这里就是DRF重写dispatch中对request的第二次封装,initialize_request里面是走的Request的内部__init__方法, self._request = request
self.request = request
self.headers = self.default_response_headers
try: # try里面的内容和原装View里面dispatch的方法完全一样,即通过__getattr__方法,先从self._request反射取属性,没取到的话再从drf的request中取
self.initial(request, *args, **kwargs)
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed response = handler(request, *args, **kwargs) except Exception as exc:
response = self.handle_exception(exc) self.response = self.finalize_response(request, response, *args, **kwargs) # 这里是对于response的第二次封装,也就是对于响应模块的第二次封装
return self.response

响应模块(response)

概念

响应模块的主要作用就是根据用户发送来的URL来筛选出对应的渲染组件,然后将内容渲染好发给用户.

现在的主流框架所包含的内置渲染器大多包含三种

  1. JSONRenderer:显示json格式
  2. BrowsableAPIRenderer:默认显示格式
  3. HTMLFormRenderer:显示form表单格式

Response类生成对象需要参数,以及生成的对象可以使用一些属性

  • 参数: Response(data = 响应的数据,status = 响应的网络状态码, headers = 想通过响应头再携带部分信息给前端)
  • 属性: response.data response.status_code response.status_text

使用方法

响应模块的使用方法常有两种,局部使用和全局使用

局部使用

# 应用名/views.py
from rest_framework.renderers import JSONRenderer, HTMLFormRenderer, BrowsableAPIRenderer
from rest_framework.views import APIView class BookDetailView(AIPView):
renderer_classes = [JSONRenderer,HTMLFormRenderer, BrowsableAPIRenderer] # 括号内即是后端允许前端的渲染格式
def get(self,request,pk):
return Response(bs.data)

全局使用

全局使用的话需要在settings.py里面配置选项

# settings.py
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES':[
'rest_framework.renderers.JSONRenderer'
]
} # 在全局配置之后就不用再view视图函数里面配置了,全局的组件都会适用这个规则

response源码简单分析:

# response的源码主要在Response类的__init__方法中

# 可以从下面的Response里面点进去Response方法
from rest_framework.response import Response # response.py,14到47行,
class Response(SimpleTemplateResponse):
def __init__(self, data=None, status=None,
template_name=None, headers=None,
exception=False, content_type=None): # 这里就是对response的初始化
super().__init__(None, status=status)
self.data = data # 给当前响应赋新属性,包括data,content_type等
self.template_name = template_name
self.exception = exception
self.content_type = content_type

解析模块(parse)

概念

解析模块的主要作用就是根据前端发来的请求头(content-type)的不同选择对应的解析器对请求内容进行处理,常用的请求头有application/json,x-www-form-urlencoded,form-data等格式.

使用方法

全局使用

全局使用解析器非常简单,直接在settings.py里面配置就行了

# settings.py
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES':[
'rest_framework.parsers.JSONParser', # 允许json格式
# 'rest_framework.parsers.FormParser', # 允许form-urlencoded
# 'rest_framework.parsers.MultiPartParser', # 允许form-data格式
]
}
# 上面配置完之后就可以在全局适用解析模块 # urls.py
from django.conf.urls import url
from api import views urlpatterns = [
url(r'^test/', views.TestView.as_view())
] # views.py
class TestView(APIView):
def post(self, request, *args, **kwargs):
print(request.content_type) # 因为全局配置我们只有JSONParser,所以发送来的请求只有content_type为JSONParser时才能正确解析,request.POST里面才会有值.
print(request.data)
print(request.POST)
print(request.FILES)
return Response('POST请求,响应内容') def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容')

局部使用

局部使用也非常简单,只需要在需要使用解析器的地方加上parser_classes=[]就行了.

# urls.py
from django.conf.urls import url
from api import views urlpatterns = [
url(r'^test/', views.TestView.as_view())
] # views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from api import models
from rest_framework.parsers import JSONParser,FormParser,MultiPartParser class TestView(APIView):
parser_classes = [JSONParser,FormParser,MultiPartParser] # 这里就是局部配置的配置项,括号里有的数据格式允许解析和传送,没有的数据将会被拒绝
def post(self, request, *args, **kwargs):
print(request.content_type)
print(request.data)
print(request.POST)
print(request.FILES)
return Response('POST请求,响应内容') def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容')

parse源码分析

# parse的源码存在于dispatch的initialize_request方法中
# /rest_framework/views.py
# 381到393行
def initialize_request(self, request, *args, **kwargs):
parser_context = self.get_parser_context(request) #这里提供要解析的数据 return Request(
request,
parsers=self.get_parsers(), #这里提供要解析的类对象
authenticators=self.get_authenticators(),
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)

DRF的请求响应组件的更多相关文章

  1. 第二章、drf框架 - 请求模块 | 渲染模块 解析模块 | 异常模块 | 响应模块 (详细版)

    目录 drf框架 - 请求模块 | 渲染模块 解析模块 | 异常模块 | 响应模块 Postman接口工具 drf框架 注册rest_framework drf框架风格 drf请求生命周期 请求模块 ...

  2. python 全栈开发,Day100(restful 接口,DRF组件,DRF跨域(cors组件))

    昨日内容回顾 1. 为什么要做前后端分离? - 前后端交给不同的人来编写,职责划分明确.方便快速开发 - 针对pc,手机,ipad,微信,支付宝... 使用同一个接口 2. 简述http协议? - 基 ...

  3. DRF之解析器组件及序列化组件

    知识点复习回顾一:三元运算 三元运算能够简化我们的代码,  请看如下代码: # 定义两个变量 a = 1 b = 2 # 判断a的真假值,如果为True,则将判断表达式的前面的值赋给c,否则将判断表达 ...

  4. DRF内置认证组件之自定义认证系统

    自定义token认证 我们知道,在django项目中不管路由以及对应的视图类是如何写的,都会走到 dispatch 方法,进行路由分发, 在阅读 APIView类中的dispatch 方法的源码中,有 ...

  5. DRF框架之认证组件用法(第四天)

    1. 什么是drf 框架的认证组件: auth 就等于是jango中的Auth模块,Auth是自带session信息,但是 drf的认证组件可以自定义token携带过去,去判断用的 2.如何实现认证呢 ...

  6. 第一篇 Flask基础篇之(配置文件,路由系统,模板,请求响应,session&cookie)

    Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后 ...

  7. 【DRF框架】认证组件

    DRF框架的认证组件 核心代码:       self.perform_authentication(request)  框架自带模块:    from rest_framework import a ...

  8. 【DRF框架】序列化组件

    DRF框架的序列化组件 在前后端分离的应用模式中,后端仅返回前端所需的数据,返回的数据类似是JSON,因此需要使用序列化组件进行序列化再将数据返回 使用JsonResponse做序列化 #  使用Js ...

  9. 基于Netty和SpringBoot实现一个轻量级RPC框架-Client端请求响应同步化处理

    前提 前置文章: <基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇> <基于Netty和SpringBoot实现一个轻量级RPC框架-Server篇> & ...

随机推荐

  1. chromedriver安装(谷歌浏览器驱动安装)

    如果程序执行错误,浏览器没有打开,那么应该是没有装 Chrome 浏览器或者 Chrome 驱动没有配置在环境变量里.下载驱动,然后将驱动文件路径配置在环境变量即可. chromedriver下载地址 ...

  2. 3、Cookie与Session之间有哪些区别或者是优缺点?

    Cookie与Session之间有哪些区别或者是优缺点? 知道了Cookie与Session,我们来做一些简单的总结:   1.Cookie可以存储在浏览器或者本地,session只能存在服务器    ...

  3. Spark:三种任务提交流程standalone、yarn-cluster、yarn-client

    spark的runtime参考:Spark:Yarn-cluster和Yarn-client区别与联系浪尖分享资料 standalone Spark可以通过部署与Yarn的架构类似的框架来提供自己的集 ...

  4. error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "stdafx.h"”?

    解决方案: 属性>预编译头>不使用预编译头>应用

  5. string中的stringstream

    博客: 加速:ios::sync_with_stdio(false); 举个例子: 題目:输入的第一行有一个数字 N 代表接下來有 N 行资料,每一行资料里有不固定个数的整数(最多20个,每行最大20 ...

  6. 使用Swagger2Markup归档swagger生成的API文档

    文章出处: http://blog.didispace.com/swagger2markup-asciidoc/ 说明 项目中使用Swagger之后,我们能够很轻松的管理API文档,并非常简单的模拟接 ...

  7. 在vue中运用mt-loadmore 实现上拉加载,下拉刷新

    元旦了,给手残党直接复制的机会,代码如下: 1. :style="{'-webkit-overflow-scrolling': scrollMode}" 最外层div设置,以便兼容 ...

  8. 创建UI的线程才能访问UI,那么怎样才算访问UI呢

    只有创建UI元素的线程(主线程又叫UI线程)才能访问UI元素.在UI线程中工作,不会有这个问题. 在后台线程中,如果直接访问UI元素,会抛出 “调用线程无法访问此对象,因为另一个线程拥有该对象” 异常 ...

  9. Linux 网络 tcp C/S通信模型

    C/S模型就是server 与 client 的模型 TCP服务器模型流程图                                                              ...

  10. 代码托管平台--GitHub 使用小结

    一.GitHub介绍 GitHub是一个面向开源及私有软件项目的托管平台,因为只支持git作为唯一的版本库格式进行托管.在GitHub,用户可以十分轻易地找到海量的开源代码. 很多IT行业的人到求职的 ...