DRF的请求响应组件
DRF的请求响应组件
下面我们介绍DRF的请求响应组件,主要包括三种,即请求模块,响应模块和解析模块.另外还有两个常用的相关模块,即渲染模块和异常模块.我们分别从模块的使用和源码分析来介绍,这里我们安装的DRF版本是最原始的0.1.0,所以下面的源码都是以这个版本为准的.
请求模块(request)
概念
drf的请求模块其实是在wsgi的request基础上再次封装,wsgi中的request模块是作为drf里面新的request模块的一个属性,名为_request,并对其完全兼容,且对于数据的解析鼓风机啊规范化,所有url拼接的参数都存放在了query_params
中,而所有的数据包数据都被解析并存放在了data
中,且query_params
和data
都是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来筛选出对应的渲染组件,然后将内容渲染好发给用户.
现在的主流框架所包含的内置渲染器大多包含三种
- JSONRenderer:显示json格式
- BrowsableAPIRenderer:默认显示格式
- 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的请求响应组件的更多相关文章
- 第二章、drf框架 - 请求模块 | 渲染模块 解析模块 | 异常模块 | 响应模块 (详细版)
目录 drf框架 - 请求模块 | 渲染模块 解析模块 | 异常模块 | 响应模块 Postman接口工具 drf框架 注册rest_framework drf框架风格 drf请求生命周期 请求模块 ...
- python 全栈开发,Day100(restful 接口,DRF组件,DRF跨域(cors组件))
昨日内容回顾 1. 为什么要做前后端分离? - 前后端交给不同的人来编写,职责划分明确.方便快速开发 - 针对pc,手机,ipad,微信,支付宝... 使用同一个接口 2. 简述http协议? - 基 ...
- DRF之解析器组件及序列化组件
知识点复习回顾一:三元运算 三元运算能够简化我们的代码, 请看如下代码: # 定义两个变量 a = 1 b = 2 # 判断a的真假值,如果为True,则将判断表达式的前面的值赋给c,否则将判断表达 ...
- DRF内置认证组件之自定义认证系统
自定义token认证 我们知道,在django项目中不管路由以及对应的视图类是如何写的,都会走到 dispatch 方法,进行路由分发, 在阅读 APIView类中的dispatch 方法的源码中,有 ...
- DRF框架之认证组件用法(第四天)
1. 什么是drf 框架的认证组件: auth 就等于是jango中的Auth模块,Auth是自带session信息,但是 drf的认证组件可以自定义token携带过去,去判断用的 2.如何实现认证呢 ...
- 第一篇 Flask基础篇之(配置文件,路由系统,模板,请求响应,session&cookie)
Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后 ...
- 【DRF框架】认证组件
DRF框架的认证组件 核心代码: self.perform_authentication(request) 框架自带模块: from rest_framework import a ...
- 【DRF框架】序列化组件
DRF框架的序列化组件 在前后端分离的应用模式中,后端仅返回前端所需的数据,返回的数据类似是JSON,因此需要使用序列化组件进行序列化再将数据返回 使用JsonResponse做序列化 # 使用Js ...
- 基于Netty和SpringBoot实现一个轻量级RPC框架-Client端请求响应同步化处理
前提 前置文章: <基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇> <基于Netty和SpringBoot实现一个轻量级RPC框架-Server篇> & ...
随机推荐
- Android API Levels 详解
Android API Levels 当你开发你的Android应用程序时,了解该平台API变更管理的基本方法和概念是很有帮助的.同样的,知道API级别标识以及该标识如何保障你的应用与实际硬件设备相兼 ...
- thinkphp ajax调用demo
http://files.cnblogs.com/files/jxkshu/tp_ckgd.rar
- Java-Class-@I:io.swagger.annotation.ApiOperation
ylbtech-Java-Class-@I:io.swagger.annotation.ApiOperation 1.返回顶部 2.返回顶部 1. package com.ylbtech.api. ...
- 记录解决java.io.IOException: Server returned HTTP response code: 500 for URL:xxxxxxxx
踩坑经历 因为项目需要去对接别的接口,使用URLConnection POST请求https接口,发送json数组时遇到java.io.IOException: Server returned HTT ...
- 屏幕左侧鼠标常驻,隐藏部分显示,文章鼠标常驻,隐藏部分隐藏(我的hexo next博客)
文章目录 如图 功能 代码 博客地址:https://mmmmmm.me 源码:https://github.com/dataiyangu?tab=repositories 如图 功能 最左侧添加透明 ...
- 安卓apk反编译、修改、重新打包、签名全过程
首先明确,反编译别人apk是一件不厚道的事情.代码是程序员辛苦工作的成果,想通过这种手段不劳而获,是不对的.这也说明,代码混淆是非常重要的.本文抱着学习的态度,研究在一些特殊的情况下如果有需要,该怎么 ...
- vue-lic工具搭建vue-webpack项目
1.安装node环境(安装node时候会自动安装npm) 参考官网:https://nodejs.org/en/download/ 2.安装vue的脚手架工具vue-cli // 全局安装 npm i ...
- 42-Ubuntu-用户管理-07-修改权限命令介绍
修改文件权限 序号 命令 作用 01 chown 修改文件/目录拥有者 02 chgrp 修改文件/目录所在主组 03 chmod 修改文件/目录权限 chmod chown chgrp ...
- 装箱与拆箱(TDB)
装箱:把值类型转换为引用类型 拆箱:把引用类型转换为值类型 只能对之前装箱的变量进行拆箱.需要强制转换.
- SetupFactory 许可协议设置
我用的SetupFactory版本是9.1.0 没有汉化 一开始自己也不知道 百度发现有人在问同样的问题但是没解决 自己找了一会偶然发现 界面左侧 Screens->Before Install ...