Django基础(5):views视图函数
1|0一、Django的视图函数view
一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应。
响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片。
无论视图本身包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你当前项目目录下面。除此之外没有更多的要求了——可以说“没有什么神奇的地方”。为了将代码放在某处,大家约定成俗将视图放置在项目(project)或应用程序(app)目录中的名为views.py的文件中。
1|11.1 一个简单的视图
下面是一个以HTML文档的形式返回当前日期和时间的视图:
让我们来逐行解释下上面的代码:
-
首先,我们从 django.http模块导入了HttpResponse类,以及Python的datetime库。
-
接着,我们定义了current_datetime函数。它就是视图函数。每个视图函数都使用HttpRequest对象作为第一个参数,并且通常称之为request。
注意,视图函数的名称并不重要;不需要用一个统一的命名方式来命名,以便让Django识别它。我们将其命名为current_datetime,是因为这个名称能够比较准确地反映出它实现的功能。
-
这个视图会返回一个HttpResponse对象,其中包含生成的响应。每个视图函数都负责返回一个HttpResponse对象。
Django使用请求和响应对象来通过系统传递状态。
当浏览器向服务端请求一个页面时,Django创建一个HttpRequest对象,该对象包含关于请求的元数据。然后,Django加载相应的视图,将这个HttpRequest对象作为第一个参数传递给视图函数。
每个视图负责返回一个HttpResponse对象。
视图层,熟练掌握两个对象即可:请求对象(request)和响应对象(HttpResponse)。
2|0二、请求对象request
2|12.1 简单过程
当一个页面被请求时,Django就会创建一个包含本次请求原信息(请求报文中的请求行、首部信息、内容主体等)的HttpRequest对象。Django会将这个对象自动传递给响应的视图函数,一般视图函数约定俗成地使用 request 参数承接这个对象。
2|22.2 请求相关的常用值
2|32.3 属性
所有的属性应该被认为是只读的,除非另有说明。
上传文件示例
2|42.4 方法
可以按照下面的练习一下:
注意:键值对的值是多个的时候,比如checkbox类型的input标签,select标签,需要用:
3|0三、响应对象HttpResponse
与由Django自动创建的HttpRequest对象相比,HttpResponse对象是我们的职责范围了。我们写的每个视图都需要实例化,填充和返回一个HttpResponse。
HttpResponse类位于django.http模块中。
3|13.1 简单使用
传递字符串
设置或删除响应头信息
属性
3|23.2 JsonResponse对象(后面再学)
JsonResponse是HttpResponse的子类,专门用来生成JSON编码的响应。
class JsonResponse
(data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None,**kwargs)
这个类是HttpRespon的子类,它主要和父类的区别在于:
1. 它的默认Content-Type 被设置为: application/json
2. 第一个参数,data应该是一个字典类型,当 safe 这个参数被设置为:False ,那data可以填入任何能被转换为JSON格式的对象,比如list, tuple, set。 默认的safe 参数是 True. 如果你传入的data数据类型不是字典类型,那么它就会抛出 TypeError的异常。
3. json_dumps_params参数是一个字典,它将调用json.dumps()方法并将字典中的参数传入给该方法。
使用HttpResponse对象来响应数据的时候,还可以通过content_type指定格式:
前端调试窗口就可以看到这个类型
如果不写这个参数是这个类型:长得像json格式的字符串,当然也可以转换成json的
看下面这种,JsonResponse默认就是content_type="application/json"。
默认只能传递字典类型,如果要传递非字典类型需要设置一下safe关键字参数。
3|33.3 具体响应方法
响应对象主要有三种形式:
- HttpResponse()
- render()
- redirect()
3.3.1 HttpResponse
HttpResponse()括号内直接跟一个具体的字符串作为响应体,比较直接很简单,所以这里主要介绍后面两种形式。
3.3.2 render
结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。
参数:
一个简单的例子:
上面的代码等于(了解):
3.3.3 redirect
给浏览器了一个30x的状态码。
引子
那么为什么不给他新的?原来的老用户只是知道你的老网站。当然这只是一些情况,其实redirect具体用法还有很多,他的参数可以是:
1. 一个模型:将调用模型的get_absolute_url() 函数
2.一个视图,可以带有参数:将使用urlresolvers.reverse 来反向解析名称
3.一个绝对的或相对的URL,将原封不动的作为重定向的位置。
默认返回一个临时的重定向;传递permanent=True 可以返回一个永久的重定向。
你可以用多种方式使用redirect() 函数。
1. 传递一个具体的ORM对象(了解即可)
将调用具体ORM对象的get_absolute_url() 方法来获取重定向的URL:
2. 传递一个视图的名称
3. 传递要重定向到的一个具体的网址
4. 当然也可以是一个完整的网址
接下来我们做一个登录成功跳转的例子。
先说一下需求:我们先要写一个登录的页面,如果登录成功之后,返回此网站的主页。这个需求比较简单,之前我们已经做过,主要是对比登录成功之后:返回页面、跳转页面哪个用户体验感更好。
配置项目的urls:
配置views函数:
配置html:
login.html
home.html
如果使用render,url不变,只是返回一个新页面:
如果使用redirect,这个是直接跳转一个新的url并且返回一个新页面:
显然,登录成功之后,利用redirect跳转页面更合理并且用户体验感会更好一些,因为url含有login本身就是与登录相关的,首页放在这个url不合适。市面上基本上所有的登录成功之后都是重定向url的。
接下来我们在看看重定向的网络请求是什么过程的:
当我登录成功之后,重定向的页面出现了两次网络请求,请看下面的图:
当我提交login页面时,login页面发出了一个location:home,location我们前端讲过这个就是页面跳转呀!这里有一个状态码,302.然后又发送了一个对/home/ 路径的请求,后端接收到此请求,返回了一个页面。
redirect:告诉浏览器给这个网址在发送一个请求。后面真正做登录的时候,我们在详细说一下这个重定向。响应相关还有一个方法叫做JsonResponse,这个我们后面会讲到。
重定向状态码
接下来我们讨论一下这个重定向的状态码301,302。这个两个状态码面试经常问到。
对普通用户来说是没什么区别的,它主要面向的是搜索引擎的机器人。
A页面临时重定向到B页面,那搜索引擎收录的就是A页面。
A页面永久重定向到B页面,那搜索引擎收录的就是B页面。
用redirect可以解释APPEND_SLASH的用法!这个不讲~~
4|0四、 CBV和FBV
FBV(function base views) 就是在视图里使用函数处理请求。之前都是FBV模式写的代码,所以就不写例子了。
CBV(class base views) 就是在视图里使用类处理请求。
Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承、封装、多态)。所以Django在后来加入了Class-Based-View。可以让我们用类写View。这样做的优点主要下面两种:
- 提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
- 可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性
4|14.1 CBV演示简单登录流程
CBV与FBV在url、views写法上有一些不同,下面有一些细节一定要注意。
views视图函数
urls路由
CBV传参,和FBV类似,有名分组,无名分组
url写法:无名分组的
templates的html
login.html
别忘了settings中间件注释掉。这样启动项目之后,我们就完成了一个简单的登录功能。
补充一个类的写法
类写法:
添加类的属性可以通过两种方法设置,第一种是常见的Python的方法,可以被子类覆盖。
第二种方法,你也可以在url中指定类的属性:
在url中设置类的属性Python
4|24.2 执行流程的源码解析
1. 请求发送到这里,先要执行as_view()方法。
views.py里面的Login是一个类,类.方法(),那么这个as_view()方法肯定是静态方法或者类方法,但是我们定义Login类时没有定义这个方法,只能从父类查找,也就是查找源码的View。
2. 执行父类View里面的as_view()方法。
--
我将部分源码拿来,咱们去分析:
第一部分:
第二部分是定义了一个view函数,但是现在还没有执行此函数的执行,所以我们直接跳过分析。
第三部分:
这样三部分我们分析完成了,至此源码中的as_view()函数执行完毕,但是千万别忘了,他有个返回值就是此as_view()函数中的view函数地址。其实你自己看一下,as_view函数就是一个闭包。
3. 程序又跳转到url路由
此时url路由就变成了这个样子:
这个我们是不是似曾相识? 我们之前一直写FBV时,你没有过疑问么?当你发送一个请求时,通过url映射到相应的函数,函数是不是就直接执行了???下面是一个FBV模式,对应函数直接就会执行了。
所以!对应的view函数也会自动执行。
4. 执行源码中的view函数
源码中的view函数如下:
5. 执行源码中dispath方法。
源码中的dispatch函数如下:
仔细想想下面的图:
至此,整个流程我们就算较为详细的走完了。
思考题
这里,面试有问过,如果你用CBV模式,你的get或者post方法是从哪里执行的? 能否在get执行之前或者之后做一些特殊的操作?
5|0五、视图函数的装饰器
其实对于上面的思考题,如果你对我讲的这个流程整清楚,那么就好实现,你的get或者post方法都是在源码的dispatch方法中执行的,我们可以利用重写父类的dispatch方法,就能够对get和post请求搞事情了。但是如果我想单独对某个请求方法搞事情,那么只能加上装饰器了。也就是我们本节所讲到的功能。
5|15.1 FBV装饰器
对于FBV这种开发方式,加上装饰器很简单,就是我们之前讲过的方式。这种比较简单,我直接展示view视图函数的代码即可。
这样你后端的代码为:
所以,对于FBV模式来说,加上装饰器对我们来说易如反掌。
5|25.2 CBV装饰器
由于CBV模式是面向对象的开发方式,之前一直没有提过是否能给类的方法加上装饰器,其实是可以的。列举出以下给类的方法加装饰器的几种方式。
1.方法一:直接加装饰器。
这里我们就只是展示views函数,因为template、urls都非常简单,而且上面也有代码示例,所以就不在这里展示了。
views视图函数
2.方法二:借助method_decorator模块。
那么这两种方式都可以,为什么还要用引用模块去加装饰器呢?这里就要说一下他们的区别了,method_decorator模块相当于给你自己写的装饰器又套了一层,他与我们自己写的装饰器唯一的区别就是传递给wrapper装饰器的内层的inner函数的参数有所不同。这里我们可以在wrappr装饰器的inner函数里面打印一下参数:
通过我们对比测试,说一下不同:
将自定义的装饰器装饰类中的方法:传给inner闭包函数的参数与该方法中的参数一致:在我们的例子中有:self,request。引用method_decorator包装的装饰器装饰类中的方法:传给inner闭包函数的参数不会传递self,在我们的例子中:只有request。
3. 方式三:给所有的方法都加上装饰器
我们上面两种方法都是单独给某个方法加上装饰器,那么我们如何给这个类的所有方法都加上装饰器呢?有同学说这个你给每个方法上面加上@wrapper不就行了,这样太low了。有没有更简单的方式呢?那就要想到我们的源码dispatch方法。我们可以在子类中重写父类的dispatch方法,因为无论执行什么请求方法(post,get,push,delete等等)都是dispatch方法利用反射调用的。所以,我们给此方法加上装饰器即可。
4. 方式四:直接在类上加装饰器(不常用)。
注意:
注意csrf-token装饰器的特殊性,在CBV模式下它只能加在dispatch上面(后面再说)
下面这是csrf_token的装饰器:
@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置csrfToken全局中间件。
@csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
注意:from django.views.decorators.csrf import csrf_exempt,csrf_protect
__EOF__

本文链接:https://www.cnblogs.com/dongye95/p/13436184.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!