Django视图类View源码分析

2023-11-16

Django视图类View源码分析

一、视图函数

django中的视图函数,就是视图功能由函数实现。

响应:或渲染模板后返回HTML,或直接返回JSON数据。

参数:视图函数的第一个参数必须是request对象。

文本响应
from django.http import HttpRequest,HttpResponse,JsonResponse
def test_index(request:HttpRequest):
    data = 'Test String'
    return HttpResponse(data)
JSON响应
from django.http import HttpRequest, HttpResponse, JsonResponse
def test_index(request:HttpRequest):
    data = [1, 2, 3]
    return JsonResponse(data)

这里会抛异常,TypeError: In order to allow non-dict objects to be serialized set the safe

parameter to False. 。意思是,safe参数为False才可使用非字典数据,所以,除非有必要,否则还

是使用字典

from django.http import HttpRequest, HttpResponse, JsonResponse
def test_index(request:HttpRequest):
    data = {'a':100, 'b':'abc'}
    return JsonResponse(data)
请求方法限制装饰器

需求:如果需要对请求方法进行限制,例如:只允许GET方法请求,可以自己判断,也可以使用Django提供的装饰器函数。

自己判断:

from django.http import HttpResponse, HttpRequest, JsonResponse
def index(request:HttpRequest, *args, **kwargs):
    print('~' * 30)
    print(request, args, kwargs)
    print(request.GET, request.method)
    print('~' * 30)
    if (request.method.lower() in ['get', 'post']):
        return JsonResponse({'a':100, 'b':'abc'})
    else:
        return JsonResponse({}, status=405)

装饰器函数

from django.http import HttpRequest, HttpResponse, JsonResponse
from django.views.decorators.http import require_http_methods, require_GET, 
require_POST, require_safe
# @require_http_methods(['GET', 'POST'])
# @require_GET
@require_POST
def test_index(request:HttpRequest):
    data = {'a':100, 'b':'abc'}
    return JsonResponse(data)

url.py

urlpatterns = [
    path('',test_index), #路径映射,路径 为/emp
    #as_view 当做视图函数,伪装成视图函数,封装成视图函数
   # path('test/',TestView.as_view()),
    path('dujie/',test_index)
]

测试过程中,当使用不被允许的方法请求时,会返回405状态码,表示Method Not Allowed ,如下图

装饰完后,test_index 就是新的视图函数,装饰器内部的inner函数。

请添加图片描述

请添加图片描述

二、视图类

视图类就是视图功能由一个类和其方法实现

参考:https://docs.djangoproject.com/en/3.2/topics/class-based-views/

请添加图片描述

View类实现原理分析

可以看到官方文档上实现视图类,在urlpatterns定义中,路径映射的应该是函数,而AboutView是一个类并不是函数,所以他使用的是AboutView.as_view() ,下面来分析下,

一级路由配置如下:

# 主路由,一级路由,根路由
urlpatterns = [
    path('emp/', include('employee.urls')) # /emp/
]

employee/urls.py如下

# 二级路由,应用路由
from django.urls import path
from .views import TestView # 视图类
urlpatterns = [
    path('test/', TestView.as_view()), # /emp/test/
]

django.views.View类,定义了http的方法的小写名称列表,这些小写名称其实就是处理请求方法名的小写。

View类的类方法as_view()方法调用后返回一个内建的view(request,args,*kwargs)新函数,本质上,其实url还是映射到这个函数上。

请求request到来后,直接发给TestView.as_view() 函数,TestView.as_view()函数内部

  • 构建TestView实例self。下面可以看源码,每一个请求都会创建一个实例
  • dispath派发请求,self.dispath(request,args,*kwargs)

dispath方法内部对比请求方法method,如果存在请求的get、post等方法,则调用,否则返回405,

本质上,as_view()方法还是把一个类封装成一个视图函数。
这个视图函数,内部使用了一个分发函数,使用请求方法名称把请求分发给存在的同名函数处理

as_view源码分析

     ##请求方法列表
     http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']

      ## classonlymethod 规定了as_view只能由class调用,所以只能是TestView.as_view()这么调用
    @classonlymethod
    ## 这里的第一个参数cls就是TestView
    def as_view(cls, **initkwargs):
        ## 这个函数其实就是url真正映射的视图函数,第一个参数必须是request
        def view(request, *args, **kwargs):
            ## 这里就是将传入到class类实例化,每一个请求都会实例化一次,互补干扰
            self = cls(**initkwargs)
            self.setup(request, *args, **kwargs)
            if not hasattr(self, 'request'):
                raise AttributeError(
                    "%s instance has no 'request' attribute. Did you override "
                    "setup() and forget to call super()?" % cls.__name__
                )
            ##dispath 派发请求
            return self.dispatch(request, *args, **kwargs)
        ## 将视图函数返回
        return view
    
    def dispatch(self, request, *args, **kwargs):
        # Try to dispatch to the right method; if a method doesn't exist,
        # defer to the error handler. Also defer to the error handler if the
        # request method isn't on the approved list.
        ## 这里判断请求的类型是否在定义好的method_names列表中
        if request.method.lower() in self.http_method_names:
        #如果存在则调用反射函数,判断是否有相关get、post等方法,如果没有则调用默认值函数self.http_method_not_allowed返回405
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
        #如果请求方法不存在定义好的列表中,则直接调用notallow函数返回405
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)
    
    def http_method_not_allowed(self, request, *args, **kwargs):
        logger.warning(
            'Method Not Allowed (%s): %s', request.method, request.path,
            extra={'status_code': 405, 'request': request}
        )
        return HttpResponseNotAllowed(self._allowed_methods())
视图类实现
from django.http import HttpRequest, HttpResponse, JsonResponse
from django.views import View
class TestIndex(View):
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)
    def get(self, request): # 支持GET
        data = {'a':100, 'b':'abc'}
        return JsonResponse(data)
    def post(self, request): # 支持POST
        data = {'a':200, 'b':'xyz'}
        return JsonResponse(data)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Django视图类View源码分析 的相关文章

  • 如何删除 PyCharm 中的项目?

    如果我关闭一个项目 然后删除该项目文件夹 则在 PyCharm 重新启动后 会再次创建一个空的项目文件夹 只需按顺序执行以下步骤即可 他们假设您当前在 PyCharm 窗口中打开了该项目 单击 文件 gt 关闭项目 关闭项目 在 PyCha
  • python array(10,1) 和 array(10,) 之间的区别

    我正在尝试将 MNIST 数据集加载到数组中 当我使用 X train y train X test y test mnist load data 我得到一个数组 y test 10000 但我希望它的形状为 10000 1 数组 1000
  • 如何获取numpy.random.choice的索引? - Python

    是否可以修改 numpy random choice 函数以使其返回所选元素的索引 基本上 我想创建一个列表并随机选择元素而不进行替换 import numpy as np gt gt gt a 1 4 1 3 3 2 1 4 gt gt
  • 是否有一个包可以维护所有带有符号的货币列表?

    是否有一个 python 包提供所有 或相当完整 货币的列表与符号 如美元的 有优秀的pycountry 贪财的 https github com limist py moneyed and ccy http code google com
  • OpenCV 跟踪器:模型未在函数 init 中初始化

    在视频的第一帧 我运行一个对象检测器 它返回对象的边界框 如下所示
  • python 中的 h2o 框架子集

    如何在 python 中对 h2o 框架进行子集化 如果 x 是一个 df 并且 Origin 是一个变量 那么在 pandas 中我们通常可以通过以下方式进行子集化 x x Origin AAF 但使用 h2o 框架会出现以下错误 H2O
  • 在Python中读取tiff标签

    我正在尝试用 Python 读取 tiff 文件的标签 该文件是 RGB 的uint16每个通道的值 我目前正在使用tifffile import tifffile img tifffile imread file tif 然而 img是一
  • 更改QLineEdit的ClearButton图标

    我想在Windows 10 1909 64位 上的Python 3 8和PyQt5 5 15 0 上更改我的QLineEdit的ClearButton图标 稍后我想在Linux上运行代码 我尝试应用此处找到的代码 如何在 QLineEdit
  • 在 Mac OS X 上安装 libxml2 时出现问题

    我正在尝试在我的 Mac 操作系统 10 6 4 上安装 libxml2 我实际上正在尝试在 Python 中运行 Scrapy 脚本 这需要我安装 Twisted Zope 现在还需要安装 libxml2 我已经下载了最新版本 2 7 7
  • django orm:select_lated,用假外键欺骗反向外键除了模型之外,会出现什么问题?

    我正在尝试学习如何使用 Django 的 ORM 进行更高级的查询 而不是使用原始 sql select related进行连接以减少数据库命中 原则上它可以进行我手动执行的连接 但有一个问题 它不使用反向外键关系来制作sql 对于我的架构
  • Jupyter 笔记本中未显示绘图图表

    我已经尝试解决这个问题几个小时了 我按照上面的步骤操作情节网站 https plot ly python getting started start plotting online并且图表仍然没有显示在笔记本中 这是我的情节代码 color
  • App Engine 实体到字典

    将 google app engine 实体 在 python 中 复制到字典对象的好方法是什么 我正在使用 db Expando 对象 所有属性均为扩展属性 Thanks 有一个名为foo尝试 foo dict
  • Flask 应用程序路由中的多个参数

    烧瓶怎么写app route如果我在 URL 调用中有多个参数 这是我从 AJax 调用的 URL http 0 0 0 0 8888 createcm summary VVV change Feauure 我试图写我的烧瓶app rout
  • 为正则表达式编写解析器

    即使经过多年的编程 我很羞愧地说我从未真正完全掌握正则表达式 一般来说 当问题需要正则表达式时 我通常可以 在一堆引用语法之后 想出一个合适的正则表达式 但我发现自己越来越频繁地使用这种技术 所以 自学并理解正则表达式properly 我决
  • 无法在 PyCharm 版本 9.3.3 中安装 NumPy。 Python版本3.8.2

    在 PyCharm 中安装 NumPy 时出错 尝试安装 Microsoft Visual C 14 0 还是行不通 NumPy 正在通过命令安装pip3 install numpy在 cmd 终端中 但是当尝试将其安装在 PyCharm
  • Discord.py 嵌入中禁用按钮/冻结按钮

    I m trying to make a replica of this bot in which when I press any of the buttons below it shows a dropdown menu and you
  • 非法指令:MacOS High Sierra 上有 4 条指令

    我正在尝试在 pygame 3 6 中制作一个看起来像聊天的窗口 我刚刚将我的 MacBook 更新到版本 10 13 6 在我这样做之前它工作得很好 但在我收到消息之后 非法指令 4 Code import pygame from pyg
  • 将时间添加到日期时间

    我有一个像这样的日期字符串 然后使用strptime 所以就像这样 my time datetime datetime strptime 07 05 15 m d Y 现在我想添加 23 小时 59 分钟my time 我努力了 timed
  • 如何绘制更大的边界框和仅裁剪边界框文本 Python Opencv

    我正在使用 easyocr 来检测图像中的文本 该方法给出输出边界框 输入图像如下所示 Image 1 Image 2 使用下面的代码获得输出图像 But I want to draw a Single Bigger bounding bo
  • 如何在 scikit 中加载 CSV 数据并将其用于朴素贝叶斯分类

    尝试加载自定义数据以在 Scikit 中执行 NB 分类 需要帮助将示例数据加载到 Scikit 中 然后执行 NB 如何加载目标的分类值 使用相同的数据进行训练和测试 或使用完整的数据集进行测试 Sl No Member ID Membe

随机推荐

  • 合宙Air101+蓝牙模块,实现手机控制舵机转动

    器材 蓝牙模块JDY33 合宙Air101 接线 JDY33的串口接Air101的串口1 TX U1 RX PB 07 RX U1 TX PB 06 舵机信号线接Air101PWM0 PB 00 main lua LuaTools需要PRO
  • MIPI入门——DCS介绍

    DCS Display Command Set 即显示 控制 命令集 是DSI协议中所使用的相关 控制 命令的一个集合 显示设备 如LCD 厂商可以选择性地部分 或全部 实现DCS文档中规定的命令 为了便于理解下面的内容 首先介绍一下DSI
  • sqli-labs(24)

    这个关卡可能有时候会出现一些小问题 有时候登陆后是没有修改密码的选项的 这是因为有时候解压时logged in php文件解压不正确 重新解压即可 本关卡为二次注入 其产生原因是 服务器端虽然对用户的直接输入做了一些过滤或者将一些字符进行转
  • 数字经济专家高泽龙谈“金融元宇宙”与“元宇宙金融”

    开始聊所有话题之前 必须先说说 金融元宇宙 或者 元宇宙金融 的概念和定义 当然 前提是搞清楚 金融 和 元宇宙 百度百科中 金融 的定义 金融 Finance Finaunce 是市场主体利用金融工具将资金从资金盈余方流向资金稀缺方的经济
  • Python读取文件时出现UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position xx: 解决方案

    Python在读取文件时 with open article txt as f 打开新的文本 text new f read 读取文本数据 出现错误 UnicodeDecodeError gbk codec can t decode byt
  • electron autoUpdater热更新

    最近创建了一个electron vue项目 用到了热更新 先看效果图 话不多说 直接上代码 main目录下创建update js 代码如下 安装包helatest yml所在服务器地址 const uploadUrl http 127 0
  • 金山WPS暑期实习招聘笔试题2013-7-28

    C 试卷B卷 应聘职位1 2 姓 名 性 别 学 位 所在院校 所学专业 联系电话 电子邮件 毕业时间 获知招聘信息渠道 说明 答题时间为 100 分钟 自我判断题 请选择最符合您本人意愿的一项 1 你
  • 从项目实施层面解析STEAM教育

    转自 https baijiahao baidu com s id 1614434815561381532 wfr spider for pc 一 引言 近几年大家常常听到STEAM教育这个词 似乎一夜之间所有的培训机构的课程都变成了STE
  • 第9章_瑞萨MCU零基础入门系列教程之SCI I2C

    本教程基于韦东山百问网出的 DShanMCU RA6M5开发板 进行编写 需要的同学可以在这里获取 https item taobao com item htm id 728461040949 配套资料获取 https renesas do
  • Android-SharedPreferences实现记住密码和自动登录

    效果图 第一次进入进来 勾选记住密码和自动登录成功后 第二次进来 说明 中间存在的图片或者多余的其他部分可删掉 留下最主要的填写部分和登陆按钮即可 功能还是可以实现的 XML文件
  • QQ飞车手游设计分析

    腾讯系竞速手游的逆袭 QQ飞车手游设计分析 前言 这是中山大学数据科学与计算机学院软件工程2019年3D游戏编程与设计的作业1 导语 在中国巨大的游戏市场下 手游战场上的战火从未熄灭 其中以王者荣耀为首的MOBA类手游与以PUBG 现改名和
  • 【Flink Rest-ful API 】

    Flink 有了一些查询job状态指标的API 这些监控 API is a REST ful API 接受 HTTP 请求并返回JSON data 这些监控API以jobManager中web server 为基础 默认其监听端口为8081
  • PHPstudy安装教程

    首先简单介绍一下PHPStudy PHPStudy是一个Windows下的Apache Nginx php MYSQL的集成开发环境 PHPStudy比较适合快速的在windows下部署一个Web开发环境 而且便于安装 部署方便 服务器本身
  • linux环境下安装nginx

    一 准备安装环境 安装nginx需要系统相关插件 所以在安装前先检查哈是否有这些插件 如果没有 则要先安装这些插件 由于笔者是新的虚拟机环境 所以这些插件都没有 都需要安装 读者可以根据自己实际情况进行相关操作 1 安装 gcc gcc c
  • HTML引用公共组件

    在test html引用footer html 效果图 代码 test html div 我是頁面 div div class footer div
  • 《再也不怕elasticsearch》REST API调用

    REST API调用 大家好我是迷途 一个在互联网行业 摸爬滚打的学子 热爱学习 热爱代码 热爱技术 热爱互联网的一切 再也不怕elasticsearch系列 帅途会慢慢由浅入深 为大家剖析一遍 各位大佬请放心 虽然这个系列帅途有时候更新的
  • linux桌面小程序开发日记2(pyqt5+yolov5)

    linux桌面小程序开发日记2 使用Pyqt5 制作一个界面 并连接摄像头 最后一篇博客地址 https blog csdn net Liuchengzhizhi article details 123692365 B站视频 https w
  • VS Code Material Icon Theme插件设置自定义文件夹图标关联

    VS Code Material Icon Theme插件设置自定义文件夹图标关联 方法与分析 自定义文件夹图片命名和位置如下 vscode extensions pkief material icon theme 4 5 0 icons
  • 程序的基本结构

    程序的基本结构 1 顺序结构 2 选择结构 选择结构如下图所示 当条件成立时 执行模块A否则执行模块B 3 循环结构 循环结构又两种形式当型循环和直道型循环 当型循环 先判断条件 条件成立就反复执行程序模块 当条件不成立时结束循环 当型循环
  • Django视图类View源码分析

    Django视图类View源码分析 一 视图函数 django中的视图函数 就是视图功能由函数实现 响应 或渲染模板后返回HTML 或直接返回JSON数据 参数 视图函数的第一个参数必须是request对象 文本响应 from django