Django 知识库:as_view()解析

2023-10-30

Django 有函数视图和类视图,分别是这样用的:

# 函数视图
path(..., function_view, ...)
# 类视图
path(..., ClassView.as_view(), ...)

源码:
在这里插入图片描述
来一步步分解。

as_view() 是个类方法,它的第一个参数 cls 表示类本身,跟实例方法的 self 差不多,都是自动传入的。

进入 as_view() 后首先对传入的参数做简单的校验,避免传入的参数将类自己的关键函数名覆盖掉,或者传入类中没定义的属性。开头这个 for 循环就是干这个用的。


接着 as_view() 内部又定义了一个 view() 函数,它接收的参数和普通的函数视图是相同的: request 对象以及从 url 获取的 args 和 kwargs 参数。我们挑重点看它在干什么:
def view(request, *args, **kwargs):
    self = cls(**initkwargs)
    ...
    self.setup(request, *args, **kwargs)
    ...
    return self.dispatch(request, *args, **kwargs)

首先实例化了类自己 cls(),并赋值给 self ,也就是你编写的类视图的实例。
接着调用 self.setup() 对实例的属性进行了初始化。setup() 方法非常简单:

def setup(self, request, *args, **kwargs):
    """Initialize attributes shared by all view methods."""
    self.request = request
    self.args = args
    self.kwargs = kwargs

把接收的参数原封不动的赋值到类实例中。
这几个属性经常能用到,比如 self.kwargs.get(‘id’) 获取 url 中传递的 id 值。
view() 函数最后返回了 dispatch() ,它的源码是这样的:

class View:
    # dispatch 用到的http请求方法名 -- 杜赛注
    http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
    ...

    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.
        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
        return handler(request, *args, **kwargs)

dispatch() 非常简短,功能却非常重要:如果 request.method 是一个 GET 请求,则调用类视图 self.get() 方法,如果是 POST 请求,那就调用 self.post() 方法。这就起到根据 http 请求类型派发到不同函数的功能,这是类视图的核心了。
回到 as_view() 来,它最后做了属性赋值、修改函数签名等收尾工作后,返回了 view 函数闭包:

def as_view(cls, **initkwargs):
    ...

    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() 方法就完成了,来总结一下它的核心流程:

  1. as_view() 内部定义了 view() 函数。view() 函数对类视图进行初始化,返回并调用了 dispatch() 方法。
  2. dispatch() 根据请求类型的不同,调用不同的函数(如 get() 、 post()),并将这些函数的 response 响应结果返回。
  3. as_view() 返回了这个 view 函数闭包,供 path() 路由调用。

把核心部分拿出来就这样:
class View:
    ...
    @classonlymethod
    def as_view(cls, **initkwargs):
        ...
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            ...
            self.setup(request, *args, **kwargs)
            ...
            return self.dispatch(request, *args, **kwargs)
        ...
        return view

    def setup(self, request, *args, **kwargs):
        self.request = request
        self.args = args
        self.kwargs = kwargs

    def dispatch(self, request, *args, **kwargs):
        if request.method.lower() in self.http_method_names:
            handler = getattr(self, request.method.lower(), ...)
        ...
        return handler(request, *args, **kwargs)

结果就是 as_view() 返回了一个函数(携带着必要的参数),和你用视图函数时直接传递给路由一个函数的效果是相同的。
相当的神奇吧。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Django 知识库:as_view()解析 的相关文章

  • 如何在刻度标签和轴之间添加空间

    我已成功增加刻度标签的字体 但现在它们距离轴太近了 我想在刻度标签和轴之间添加一点呼吸空间 如果您不想全局更改间距 通过编辑 rcParams 并且想要更简洁的方法 请尝试以下操作 ax tick params axis both whic
  • 如何收集列表、字典等中重复计算的结果(或制作修改每个元素的列表的副本)?

    There are a great many existing Q A on Stack Overflow on this general theme but they are all either poor quality typical
  • 如何在android上的python kivy中关闭应用程序后使服务继续工作

    我希望我的服务在关闭应用程序后继续工作 但我做不到 我听说我应该使用startForeground 但如何在Python中做到这一点呢 应用程序代码 from kivy app import App from kivy uix floatl
  • 导入错误:没有名为 _ssl 的模块

    带 Python 2 7 的 Ubuntu Maverick 我不知道如何解决以下导入错误 gt gt gt import ssl Traceback most recent call last File
  • 如何使用 Scrapy 从网站获取所有纯文本?

    我希望在 HTML 呈现后 可以从网站上看到所有文本 我正在使用 Scrapy 框架使用 Python 工作 和xpath body text 我能够获取它 但是带有 HTML 标签 而且我只想要文本 有什么解决办法吗 最简单的选择是ext
  • 为 pandas 数据透视表中的每个值列定义 aggfunc

    试图生成具有多个 值 列的数据透视表 我知道我可以使用 aggfunc 按照我想要的方式聚合值 但是如果我不想对两列求和或求平均值 而是想要一列的总和 同时求另一列的平均值 该怎么办 那么使用 pandas 可以做到这一点吗 df pd D
  • 从 scikit-learn 导入 make_blobs [重复]

    这个问题在这里已经有答案了 我收到下一个警告 D Programming Python ML venv lib site packages sklearn utils deprecation py 77 DeprecationWarning
  • 在 NumPy 中获取 ndarray 的索引和值

    我有一个 ndarrayA任意维数N 我想创建一个数组B元组 数组或列表 其中第一个N每个元组中的元素是索引 最后一个元素是该索引的值A 例如 A array 1 2 3 4 5 6 Then B 0 0 1 0 1 2 0 2 3 1 0
  • python pandas 中的双端队列

    我正在使用Python的deque 实现一个简单的循环缓冲区 from collections import deque import numpy as np test sequence np array range 100 2 resha
  • Abaqus 将曲面转化为集合

    我一直试图在模型中找到两个表面的中心 参见照片 但未能成功 它们是元素表面 面 查询中没有选项可以查找元素表面的中心 只能查找元素集的中心 找到节点集的中心也很好 但是我的节点集没有出现在工具 gt 查询 gt 质量属性选项中 而且我找不到
  • python 集合可以包含的值的数量是否有限制?

    我正在尝试使用 python 设置作为 mysql 表中 ids 的过滤器 python集存储了所有要过滤的id 现在大约有30000个 这个数字会随着时间的推移慢慢增长 我担心python集的最大容量 它可以包含的元素数量有限制吗 您最大
  • 使用 OpenPyXL 迭代工作表和单元格,并使用包含的字符串更新单元格[重复]

    这个问题在这里已经有答案了 我想使用 OpenPyXL 来搜索工作簿 但我遇到了一些问题 希望有人可以帮助解决 以下是一些障碍 待办事项 我的工作表和单元格数量未知 我想搜索工作簿并将工作表名称放入数组中 我想循环遍历每个数组项并搜索包含特
  • ExpectedFailure 被计为错误而不是通过

    我在用着expectedFailure因为有一个我想记录的错误 我现在无法修复 但想将来再回来解决 我的理解expectedFailure是它会将测试计为通过 但在摘要中表示预期失败的数量为 x 类似于它如何处理跳过的 tets 但是 当我
  • 如何将 PIL 图像转换为 NumPy 数组?

    如何转换 PILImage来回转换为 NumPy 数组 这样我就可以比 PIL 进行更快的像素级转换PixelAccess允许 我可以通过以下方式将其转换为 NumPy 数组 pic Image open foo jpg pix numpy
  • 设置 torch.gather(...) 调用的结果

    我有一个形状为 n x m 的 2D pytorch 张量 我想使用索引列表来索引第二个维度 可以使用 torch gather 完成 然后然后还设置新值到索引的结果 Example data torch tensor 0 1 2 3 4
  • 检查所有值是否作为字典中的键存在

    我有一个值列表和一本字典 我想确保列表中的每个值都作为字典中的键存在 目前我正在使用两组来确定字典中是否存在任何值 unmapped set foo set bar keys 有没有更Pythonic的方法来测试这个 感觉有点像黑客 您的方
  • 如何从没有结尾的管道中读取 python 中的 stdin

    当管道来自 打开 时 不知道正确的名称 我无法从 python 中的标准输入或管道读取数据 文件 我有作为例子管道测试 py import sys import time k 0 try for line in sys stdin k k
  • 循环标记时出现“ValueError:无法识别的标记样式 -d”

    我正在尝试编码pyplot允许不同标记样式的绘图 这些图是循环生成的 标记是从列表中选取的 为了演示目的 我还提供了一个颜色列表 版本是Python 2 7 9 IPython 3 0 0 matplotlib 1 4 3 这是一个简单的代
  • 使用基于正则表达式的部分匹配来选择 Pandas 数据帧的子数据帧

    我有一个 Pandas 数据框 它有两列 一列 进程参数 列 包含字符串 另一列 值 列 包含相应的浮点值 我需要过滤出部分匹配列 过程参数 中的一组键的子数据帧 并提取与这些键匹配的数据帧的两列 df pd DataFrame Proce
  • Pandas 与 Numpy 数据帧

    看这几行代码 df2 df copy df2 1 df 1 df 1 values 1 df2 ix 0 0 我们的教练说我们需要使用 values属性来访问底层的 numpy 数组 否则我们的代码将无法工作 我知道 pandas Data

随机推荐

  • chatgpt赋能python:简单好玩的Python程序——让你爱上编程

    简单好玩的Python程序 让你爱上编程 Python语言在最近的几年迅速崛起成为最流行的编程语言之一 它的语法简单易懂 代码可读性强 是初学者学习编程的极佳选择 今天我想分享一些简单好玩的Python程序 让你体验Python编程的乐趣
  • 电信运营商走在云时代:从“基础联接”到“万物智联”

    从语音通话业务到互联网业务再到云计算业务 从 光改 奔向 云改 中国的运营商们正在实现基础连接到万物智联的跨越 作者 斗斗 编辑 皮爷 出品 产业家 日新月异的技术创新 为电信运营商带来了持续不断的行业变革 短短几年光景 随着移动互联网的迅
  • 【HTML+CSS+JavaScript】实现鼠标点击烟花效果

    文章目录 HTML CSS JavaScript 实现鼠标点击烟花效果 爆炸型 心型 圆形 一 效果图 二 鼠标点击烟花效果 心型实现代码 1 HTML部分代码 2 CSS部分代码 3 内部的JavaScript部分代码 三 鼠标点击烟花效
  • 伸缩自如的ElasticSearch——ElasticSearch-sql安装及使用

    文章目录 安装ElasticSearch sql 安装es sql site 安装ElasticSearch sql 安装地址 ES sql地址 注意安装版本要与ES版本一致 这里是6 7 1 安装完成后 解压 将解压后的文件夹放入ES的p
  • 【DirectX11学习01】用一个类封装DirectX的初始化

    DirectX的初始化步骤较为繁琐 这里将DX的初始化扔进类的初始化 构造函数 里 如果构造函数里还要执行其他逻辑 那就最好把D3D的初始化扔进一个内联函数 这样能够更好地区分逻辑 下次要使用的时候 就直接继承该类 然后在这基础上写自己的东
  • 软件测试c语言代码_软件测试理论知多少?

    有源医疗器械很多都是带有软件的 今天一起了解下软件测试理论 软件测试目的 软件测试定义 软件测试原则 软件测试分类 软件测试方法 测试基本流程 软件测试定义 软件测试 英语 software testing 描述一种用来促进鉴定软件的正确性
  • CVPR 2018值得一看的25篇论文,都在这里了

    作者丨李光睿 学校丨重庆大学本科在读 研究方向丨计算机视觉 Unsupervised Person Image Synthesis in Arbitrary Poses Image Synthesis CVPR 2018 Spotlight
  • 排序算法之奇偶排序

    排序算法之奇偶排序 奇偶排序的基本思想就是先对奇数列进行一趟排序 比较奇数列和其相邻的偶数列的元素 如果逆序则交换 再对偶数列进行一趟排序 比较偶数列和其相邻的奇数列的元素 如果逆序则交换 接着对奇数列进行排序 再对偶数列进行排序 重复进行
  • windows7linux双系统,win7下安装Linux实现双系统全教程

    经过大半天的摸索与实验终于在自己的电脑上成功的装上了Win7和Linux的双系统 现在我把详细的流程给大家分享了 希望有兴趣的可以去试试 下面为大家介绍win7下安装Linux实现双系统全攻略 材料 工具 4G的U盘 Linux系统 软碟通
  • 计算机wifi无法打开,教你win10系统WiFi热点无法打开的修复教程

    最近有windows10系统用户反馈 遇到了WiFi热点无法打开的问题 打开WIFI热点我们可将我们电脑的网络共享给手机 使我们的手机能够节省一些流量 怎么办呢 就此问题 接下来小编教你win10系统WiFi热点无法打开的修复教程 很多wi
  • C# 给自己写的软件,加注册码功能

    由于永和的项目里边用到了这个功能 因此在网上找到了 直接贴过来 复用一下 为自己写的程序加一个注册功能吧 生成的机器号是根据CPU和硬盘号来的 根据自己的需求改成是否是随机生成 代码直接粘贴到新建类覆盖原代码就能直接用了 using Sys
  • 探索IP地址的应用

    无论是互联网行业还是传统行业都会用到网络 作为企业如何维护网络安全 保障网站不被攻击 数据不被泄露等 这个时候我们就会通查询IP归属地 辅助企业解决安全问题 下面介绍一下ip归属地在各行业的具体应用 1 网安行业 应用一 提升企业网络资产检
  • cocos2dx使用CocosBuilder(编辑器)完成基础骨骼动画

    转载自 黑米GameDev街区 原文链接 http www himigame com cocosbuilder 1061 html 点击订阅 本博客最新动态 及时将最新博文通知您 关于CocosBuilder 已经成为cocos2d coc
  • 抖音壁纸表情包小程序源码,可对接流量主

    抖音壁纸表情包小程序源码 可对接流量主 抖音壁纸表情包小程序源码 可对接流量主 抖音壁纸表情包小程序源码 可对接流量主 抖音壁纸表情包小程序源码 可对接流量主 星光壁纸 我的页面
  • 【C语言取反运算符】~2是多少?~-5是多少?

    标题的答案 2 3 3 2 原理是什么 我们先来看这个程序及输出的结果 容易总结出这样一个结论 i i 1 为什么呢 一言以蔽之 运算符是对i的补码 含符号位 进行取反 2的原码是0000 0010 正数补码是其本身0000 0010 取反
  • angularJS项目开发需要下载安装和配置的环境

    1 node js npm命令 nodejs org nodejs安装及环境配置参见博客园某博客 地址 http www cnblogs com linjiqin p 3765390 html 2 cordova codova apache
  • Python入门之对象与变量

    一 对象 对象是Python中最基本的概念之一 在Python中 万物皆可对象 对象有三个基本属性 即类型 身份标识 值 二 变量与赋值 1 变量 在Python中 不需要事先声明变量名及其类型 直接赋值即可创建任意类型的对象变量 不仅变量
  • 基于QT4.8.6的软键盘

    这几天接到任务要写一个软键盘 用于在Linux上运行的软件 windows下也可以 效果 1 能够实现中英文 数字 字符的切换 2 并且实现单字中文 英文 数字 符号的输入 3 使用sqlite数据库 4 完全模仿手机QQ全键盘输入样式 源
  • 【Linux】VMware虚拟机安装Linux Mint系统

    1 安装准备 虚拟机软件 VMware Workstation Pro Mint系统镜像 linuxmint 20 3 cinnamon 64bit iso 下载网址可见 网易 欢迎访问网易开源镜像站 阿里 阿里巴巴开源镜像站 清华 清华大
  • Django 知识库:as_view()解析

    Django 有函数视图和类视图 分别是这样用的 函数视图 path function view 类视图 path ClassView as view 源码 来一步步分解 as view 是个类方法 它的第一个参数 cls 表示类本身 跟实