Django(47)drf请求生命周期分析

Django(47)drf请求生命周期分析前言一般我们写完序列化以后,我们就会开始写视图了,drf中我们一般使用CBV的方式,也就是类视图的方式,最基础的我们会使用fromrest_framework.viewsimportAPIVi

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

前言

  一般我们写完序列化以后,我们就会开始写视图了,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/,会出现下图样式,代表请求成功
Django(47)drf请求生命周期分析
接着我们在接口工具中使用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. 完成任务方法交给视图类函数处理,得到请求的响应结果,返回给前台
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/165431.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • STL容器分类「建议收藏」

    STL容器分类「建议收藏」容器(container)是装有其他对象的对象。容器里面的对象必须是同一类型,该类型必须是可拷贝构造和可赋值的,包括内置的基本数据类型和带有公用拷贝构造函数和赋值操作符的类。典型的容器有队列、链表和向量等。在标准C++中,容器一般用模版类来表示。不过STL不是面向对象的技术,不强调类的层次结构,而是以效率和实用作为追求的目标。所以在STL并没有一个通用的容器类,各种具体的容器也没有统一的基类。

    2025年11月3日
    2
  • 树莓派4B安装Tensorflow(Python3.5和3.7下分别进行安装)

    树莓派4B安装Tensorflow(Python3.5和3.7下分别进行安装)【前言】虽然树莓派的速度不如PC,但是它功耗小、价格便宜,很多同学都用来学习机器学习的相关课程,而且tensorflow官方是支持树莓派,我们可以直接在树莓派上进行学习。网上的现在树莓派已经发布4B,新版本的rasbian系统全面采用了python3.7,但是网上大多数教程还是基于树莓派3的,使用python3.5进行安装。我使用的是树莓派4B和2019-06-20-raspb…

    2022年6月4日
    57
  • python做语音信号处理

    python做语音信号处理作者:凌逆战时间:2019年11月1日博客园地址:https://www.cnblogs.com/LXP-Never/p/10078200.html音频信号的读写、播放及录音标准的python已经支持WAV格式的书写,而实时的声音输入输出需要安装pyAudiio(http://people.csail.mit.edu/hubert/pyaudio)。最后我们还将使用pyMedia(…

    2022年5月26日
    40
  • conda install 换源_Mac下conda环境操作、conda换源、pip换源

    conda install 换源_Mac下conda环境操作、conda换源、pip换源conda环境操作显示当前存在哪些conda环境:condaenvlist1⃣️conda创建虚拟环境:condacreate-n环境名如果需要指定某些版本,这里以指定python版本为例:condacreate-n环境名python=3.6(更新:惨痛教训,创建新的conda环境时,一定要指定python的版本,否则在pycharm中导入conda虚拟环境时,在/Users/…

    2025年6月16日
    2
  • 计算机定时关机命令,电脑定时关机怎么设置_电脑定时关机命令

    计算机定时关机命令,电脑定时关机怎么设置_电脑定时关机命令标签:电脑(142)命令(11)电脑系统WindowsXP第一种:电脑定时关机怎么设置的步骤是这样的:例如,要使电脑在23:00的时候定时自动关机,单击“开始”-“运行”命令,在打开的“运行”对话框中输入at23:00shutdown-s,单击”确定”按钮关闭“运行”对话框即可。这样,您就可以在23:00点时电脑就会弹出“系统关机”对话框,默认30秒钟倒计时并提示保存工作。(当你不想它运行…

    2022年5月14日
    37
  • 模糊神经网络FNN「建议收藏」

    模糊神经网络FNN「建议收藏」分别对调速,调压,综合系统加入FNN控制器,使PID的输出达到最小值。其中关于FNN的理论部分,由于您已经以供了较多的文献资料,这里就不再进行叙述,这里主要说明一下最后的仿真效果和S函数的大致设计流程。这里仅对调速模型进行设计说明。为了对比加入FNN控制器后的性能变化,我们同时要对有FNN控制器的模型以及没有FNN控制器的模型进行仿真,仿真结果如下所示:非FNN控制器的结构:其仿真结果如下所示:FNN控制器的结构:其仿真…

    2025年8月13日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号