前言

  一般我们写完序列化以后,我们就会开始写视图了,drf中我们一般使用CBV的方式,也就是类视图的方式,最基础的我们会使用from rest_framework.views import APIViewAPIView继承自View,关于视图的详解,我们后续再细讲。本章介绍drf的请求生命周期

前置准备工作

我们先写一个视图类TestView,代码如下:

from rest_framework.views import APIView
from rest_framework.response import Response
class TestView(APIView):
def get(self, request, *args, **kwargs):
return Response("drf get ok")
def post(self, request, *args, **kwargs):
return Response("drf post ok")

注意:这里的Response必须是drf下的Response,不能是Django原生的HttpResponse或者是JsonResponse,否则会出错

接着,在urls.py中配置路由,如下

urlpatterns = [
path('test/', views.TestView.as_view(), name="Test"),
]

然后我们访问http://127.0.0.1:8000/drf/test/,会出现下图样式,代表请求成功



接着我们在接口工具中使用POST请求方式访问,返回结果如下:

"drf post ok"

以上2种访问方式都成功了,接下来我们分析其中的请求过程以及原理

请求生命周期分析

首先我们先从路由配置中看到views.TestView.as_view(),调用的是TestView类视图下的as_view方法,但是我们上面定义该方法的时候,没有重写as_view()方法,所以会调用父类APIView中的as_view方法,源码如下:

@classmethod
def as_view(cls, **initkwargs):
"""
Store the original class on the view function. This allows us to discover information about the view when we do URL
reverse lookups. Used for breadcrumb generation.
""" # 判断queryset是否是QuerySet对象
if isinstance(getattr(cls, 'queryset', None), models.query.QuerySet):
def force_evaluation():
raise RuntimeError(
'Do not evaluate the `.queryset` attribute directly, '
'as the result will be cached and reused between requests. '
'Use `.all()` or call `.get_queryset()` instead.'
)
cls.queryset._fetch_all = force_evaluation # 调用父类的as_view方法
view = super().as_view(**initkwargs)
view.cls = cls
view.initkwargs = initkwargs # Note: session based authentication is explicitly CSRF validated,
# all other authentication is CSRF exempt.
# 禁用了csrf认证
return csrf_exempt(view)

通过这行代码view = super().as_view(**initkwargs),可以知道APIViewas_view方法也调用了父类Viewas_view方法,源码如下:

def as_view(cls, **initkwargs):
"""Main entry point for a request-response process."""
for key in initkwargs:
if key in cls.http_method_names:
raise TypeError("You tried to pass in the %s method name as a "
"keyword argument to %s(). Don't do that."
% (key, cls.__name__))
if not hasattr(cls, key):
raise TypeError("%s() received an invalid keyword %r. as_view "
"only accepts arguments that are already "
"attributes of the class." % (cls.__name__, key)) def view(request, *args, **kwargs):
self = cls(**initkwargs)
# 如果有get属性,没有head属性,那么head就是get
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get # 初始化所有视图方法共享的属性
self.setup(request, *args, **kwargs) # 如果没有request属性,报异常
if not hasattr(self, 'request'):
raise AttributeError(
"%s instance has no 'request' attribute. Did you override "
"setup() and forget to call super()?" % cls.__name__
) # 返回一个`dispatch`方法
return self.dispatch(request, *args, **kwargs)
view.view_class = cls
view.view_initkwargs = initkwargs # take name and docstring from class
update_wrapper(view, cls, updated=()) # and possible attributes set by decorators
# like csrf_exempt from dispatch
update_wrapper(view, cls.dispatch, assigned=())
return view

as_view方法返回的是viewview返回的是dispatch方法,dispatch方法也是调用的APIView下的dispatch方法,源码如下:

def dispatch(self, request, *args, **kwargs):
"""
`.dispatch()` is pretty much the same as Django's regular dispatch,
but with extra hooks for startup, finalize, and exception handling.
"""
self.args = args
self.kwargs = kwargs
# 初始化请求,返回的是Request对象
request = self.initialize_request(request, *args, **kwargs)
self.request = request
self.headers = self.default_response_headers # deprecate? try:
# 在调用方法处理程序之前运行任何需要发生的操作
self.initial(request, *args, **kwargs) # Get the appropriate handler method
# 获取request的请求方法
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) # 返回一个response响应对象
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response

dispatch返回一个response响应对象,得到请求的响应结果,返回给前台

总结

  1. url请求走的是APIViewas_view函数
  2. APIViewas_view调用父类(django原生)的as_view,还禁用了csrf认证
  3. 在父类的as_view中的dispatch方法请求走的又是APIViewdispatch
  4. 完成任务方法交给视图类函数处理,得到请求的响应结果,返回给前台

Django(47)drf请求生命周期分析的更多相关文章

  1. DRF框架(一)——restful接口规范、基于规范下使用原生django接口查询和增加、原生Django CBV请求生命周期源码分析、drf请求生命周期源码分析、请求模块request、渲染模块render

    DRF框架    全称:django-rest framework 知识点 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码 - 基于restful规范下的CBV接口 3.请求组件 ...

  2. drf复习(一)--原生djangoCBV请求生命周期源码分析、drf自定义配置文件、drf请求生命周期dispatch源码分析

    admin后台注册model  一.原生djangoCBV请求生命周期源码分析 原生view的源码路径(django/views/generic/base.py) 1.从urls.py中as_view ...

  3. Django(35)Django请求生命周期分析(超详细)

    Django请求生命周期分析 1.客户端发送请求 在浏览器输入url地址,例如www.baidu.com,浏览器会自动补全协议(http),变为http://www.baidu.com,现在部分网站都 ...

  4. DRF 请求生命周期以及各模块解析

    目录 rest_framework框架的封装特点 原生Django与DRF比较 APIView 的请求生命周期 请求模块(request) 解析模块(parser_classes) 异常模块(exce ...

  5. Django简介,请求生命周期,静态文件配置

    Web框架 ​ Web框架(Web framework)是一种开发框架,用来支持动态网站.网络应用和网络服务的开发.这大多数的web框架提供了一套开发和部署网站的方式,也为web行为提供了一套通用的方 ...

  6. drf框架概况-resful接口规范-请求模块-渲染模块-Postman-drf请求生命周期

    drf框架 全称:django-rest- framework 知识点: """ 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码-基于restful ...

  7. 3) drf 框架生命周期 请求模块 渲染模块 解析模块 自定义异常模块 响应模块(以及二次封装)

    一.DRF框架 1.安装 pip3 install djangorestframework 2.drf框架规矩的封装风格 按功能封装,drf下按不同功能不同文件,使用不同功能导入不同文件 from r ...

  8. Django框架深入了解_01(Django请求生命周期、开发模式、cbv源码分析、restful规范、跨域、drf的安装及源码初识)

    一.Django请求生命周期: 前端发出请求到后端,通过Django处理.响应返回给前端相关结果的过程 先进入实现了wsgi协议的web服务器--->进入django中间件--->路由f分 ...

  9. APIview的请求生命周期源码分析

    目录 APIview的请求生命周期源码分析 请求模块 解析模块 全局配置解析器 局部配置解析器 响应模块 异常处理模块 重写异常处理函数 渲染模块 APIview的请求生命周期源码分析 Django项 ...

随机推荐

  1. POJ2446 模板盖格子 简单二分匹配

    题意:       给你一个n*m的格子,有的格子上有坑,然后让你用1*2的东西去覆盖所有没有坑的格子,不能重叠,坑上也不能放东西覆盖,问是否能成功. 思路:        简单题目,每个格子和四周的 ...

  2. Java中常见的包

    目录 JDK自带的包 第三方包 JDK自带的包 JAVA提供了强大的应用程序接口,既JAVA类库.他包含大量已经设计好的工具类,帮助程序员进行字符串处理.绘图.数学计算和网络应用等方面的工作.下面简单 ...

  3. Windbg 字符串条件断点

    0x01 前言 Windbg 作为 Windows 下的主流调试器,除了人机交互相比其他调试器略有不足外,其他功能都是十分强大的存在. 在所有的调试器中断点功能都是必不可少的,Windbg 可以使用 ...

  4. 【点分治】2019 首尔 icpc Gene Tree

    题目 链接:https://ac.nowcoder.com/acm/contest/15644/B来源:牛客网 A gene tree is a tree showing the evolution ...

  5. git中一些常见问题的解决

    1. 解决: 先pull,执行git pull origin 分支名称:然后再执行 git push origin 分支名称 2.git报remote HTTP Basic Access denied ...

  6. Nginx超详细常用功能演示,够用啦~~~

    前言 Nginx("engine x")是一款是由俄罗斯的程序设计师Igor Sysoev所开发高性能的 Web和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服 ...

  7. Educational Codeforces Round 105 (Rated for Div. 2)

    A. ABC String 题目:就是用'('和')'来代替A,B,C并与之对应,问是不是存在这样的对应关系使得'('和')'正好匹配 思路:第一个和最后一个字母是确定的左括号或者是右括号,这样就还剩 ...

  8. str.isdigit()可以判断变量是否为数字

    字符串.isdigit()可以判断变量是否为数字 是则输出True 不是则输出False 好像只能字符串

  9. docker运行mysql数据库

    1.搜索镜像源是否有mysql镜像 执行语句: sudo docker search mysql  2.拉取需要版本的mysql,执行语句: docker pull mysql:5.7  3.查看安装 ...

  10. 啥?SynchronousQueue和钟点房一个道理

    今天这篇文章,我们继续讲架构师大刘的故事. 大刘有段时间经常会给一些程序员讲课.这一方面是由于团队培训的需要,一方面也是大刘自身想搞搞凡尔赛,嘚瑟一下自身的实力. 大刘讲课是允许公司任何一个人进去听的 ...