目录
视图(Views)是 Django的 MTV架构模式的V部分,主要负责处理用户请求和生成相应的响应内容,然后在页面或其他类型文档中显示。
1.Django5设置视图响应状态
客户端请求后端服务,在view.py视图层方法最终return返回视图响应
Python内置提供了响应类型,来实现不同的返回不同的http状态码
测试实例:
1.1HttpResponse
修改Helloword项目下的index函数:
结果:
状态码200,返回网页信息。status=200不写的话默认也是200
1.2HttpResponseNotFound 404
修改Helloword项目下的index函数:
结果:
状态码404
1.3JsonResponse 响应json数据
修改Helloword项目下的index函数:
结果:
状态码200,返回json格式数据。
如果是复杂的网页,为了较少视图函数代码量,引入模板
通过Django提供的render方法渲染数据到模板,然后在响应到页面
修改Helloword项目下的index函数:
创建html页面:
结果:
render方法的源码中,经过模版渲染后得到content网页内容,依然返回的是HttpResponse对象
- request和template_name是必须的参数。其他参数可选。
-
request:浏览器向服务器发送的请求对象,包含用户信息、请求内容和请求方式等。
-
template_name:设置模板文件名,用于生成网页内容。
-
context:对模板上下文(模板变量)赋值,以字典格式表示,默认情况下是一个空字典。
-
content_type:响应内容的数据格式,一般情况下使用默认值即可。
-
status: HTTP状态码,默认为200.
-
using:设置模板引擎,用于解析模板文件,生成网页内容。
-
2.Django5设置重定向响应
RedirectView实现重定向时,虽简单,但不灵活,需要使用redirect方法来实现业务上的判断
重定向的状态码分为301和302
301(HttpResponsePermanentRedirect):301重定向是永久的重定向,搜索引擎在抓取新内容的同时会将旧的网址替换为重定向之后的网址。
302(HttpResponseRedirect):302跳转是暂时的跳转,搜索引擎会抓取新内容而保留旧的网址。因为服务器返回302代码,所以搜索引擎认为新的网址只是暂时的。
测试案例:
编写html页面
修改Helloword项目的views下的index函数
结果:
将True改为False后的结果:
redirect方法的源码中
第一个跳转参数支持模型,视图路由名称,还有最常用得url地址;第二个参数就是是否永久跳转,默认Flase;
redirect_class通过permanent判断,true返回HttpResponsePermanentRedirect,false返回HttpResponseRedirect;
3.Django5二进制文件下载响应
响应内容除了返回网页信息外,还可以实现文件下载功能,是网站常用的功能之一。
Django提供三种方式实现文件下载功能,分别是HttpResponse、StreamingHttpResponse和 FileResponse,三者的说明如下:
-
-
HttpResponse是所有响应过程的核心类,它的底层功能类是HttpResponseBase。
-
StreamingHttpResponse是在 HttpResponseBase的基础上进行继承与重写的,它实现流式响应输出(流式响应输出是使用Python的迭代器将数据进行分段处理并传输的),适用于大规模数据响应和文件传输响应。
-
FileResponse是在StreamingHttpResponse 的基础上进行继承与重写的,它实现文件的流式响应输出,只适用于文件传输响应。
-
测试案例:
拷贝一个二进制文件:
在views.py中实现方法:
在urls.py中添加映射:
在static目录下新建一个html静态文件:
结果:
4.Http请求&HttpRequest请求类
超文本传输协议(Hypertext Transfer Protocol,HTTP)是一个简单的请求-响应协议
HTTP请求分为8种请求方式,每种请求方式的说明如下:
在上述的HTTP请求方式里,最基本的是GET请求和POST 请求,网站开发者关心的也只有GET请求和POST请求。
- GET请求和 POST请求是可以设置请求参数的,两者的设置方式如下:
-
GET请求的请求参数是在路由地址后添加“?”和参数内容,参数内容以key=value 形式表示,等号前面的是参数名,后面的是参数值,如果涉及多个参数,每个参数之间就使用“&”隔开,如127.0.0.1:8000/?name=py&pw=123456。
-
POST请求的请求参数一般以表单的形式传递,常见的表单使用HTML的 form标签,并且form标签的method 属性设为POST.
-
Django5中,Http请求信息都被封装到了HttpRequest类中。
- HttpRequest类的常用属性如下:
-
COOKIE:获取客户端(浏览器)的Cookie信息,以字典形式表示,并且键值对都是字符串类型。
-
FILES: django.http.request.QueryDict对象,包含所有的文件上传信息。
-
GET:获取GET请求的请求参数,它是django.http.request.QueryDict对象,操作起来类似于字典。
-
POST:获取POST请求的请求参数,它是django.http.request.QueryDict对象,操作起来类似于字典。
-
META:获取客户端(浏览器)的请求头信息,以字典形式存储。
-
method:获取当前请求的请求方式(GET请求或POST请求).
-
path:获取当前请求的路由地址。
-
session:一个类似于字典的对象,用来操作服务器的会话信息,可临时存放用户信息。
-
user:当 Django启用AuthenticationMiddleware中间件时才可用。它的值是内置数据模型User的对象,表示当前登录的用户。如果用户当前没有登录,那么user将设为django.contrib.auth.models.AnonymousUser的一个实例。
-
- HttpRequest类常用方法如下:
-
is_secure():是否是采用HTTPS协议。
-
get_host():获取服务器的域名。如果在访问的时候设有端口,就会加上端口号,如127.0.0.1:8000。
-
get_full path():返回路由地址。如果该请求为GET请求并且设有请求参数,返回路由地址就会将请求参数返回,如/?name=py&pw=123456。
-
在views中别写get和post方法:
在urls里添加映射:
模板中新建http测试页面
注:不能用静态页面,需要一个csrf安全机制token 需要后端server来提供,所以只能用模版 {% csrf_token %}
修改index定向页面:
打开网页测试:
点击get请求测试:
控制台输出:
输入信息,点击提交:
结果:
控制台输出:
5.会话管理(Cookies&Session)
HTTP是一种无状态协议,每次客户端访问web页面时,客户端打开一个单独的浏览器窗口连接到web服务器,由于服务器不会自动保存之前客户端请求的相关信息,所有无法识别一个HTTP请求是否为第一次访问。这就引进了web客户端和服务器端之间的会话,这就是会话管理。
常用的会话跟踪技术是Cookie与Session。
Session通过在服务器端记录信息确定用户身份
5.1Cookie
Cookie通过在客户端记录信息确定用户身份
Cookie是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息。
Cookie定义了一些HTTP请求头和HTTP响应头,通过这些HTTP头信息使服务器可以与客户进行状态交互。
5.1.1Cookie运行原理
客户端请求服务器后,如果服务器需要记录用户状态,服务器会在响应信息中包含一个Set-Cookie的响应头,客户端会根据这个响应头存储Cookie信息。再次请求服务器时,客户端会在请求信息中包含一个Cookie请求头,而服务器会根据这个请求头进行用户身份、状态等较验。
5.1.2获取cookie
5.1.3设置cookie
5.1.4删除cookie
5.2Session
Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。
客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。
客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。
5.2.1Session运行原理
当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识,称为session id
如果已包含一个session id则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(如果检索不到,可能会新建一个)
如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。
5.2.2Session配置
5.2.3Session操作
1. 获取、设置、删除Session中数据
2. 所有 键、值、键值对
3.会话session的key
4.将所有Session失效日期小于当前日期的数据删除
5.检查会话session的key在数据库中是否存在
6.删除当前会话的所有Session数据
7.删除当前的会话数据并删除会话的Cookie
8.设置会话Session和Cookie的超时时间
5.3Cookie&Session操作实例
views.py里定义两个方法,分别是登录页面跳转,以及登录逻辑处理
urls里添加映射
templates下新建login.html和main.html
login.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/login/" method="post">
{% csrf_token %}
<table>
<tr>
<td>用户登录</td>
</tr>
<tr>
<td>
用户名:
</td>
<td>
<input type="text" name="user_name">
</td>
</tr>
<tr>
<td>
密码:
</td>
<td>
<input type="password" name="user_pwd">
</td>
</tr>
<tr>
<td>
<input type="submit" value="提交">
</td>
</tr>
<tr>
<td colspan="2"><font color="red">{{ error_info }}</font></td>
</tr>
</table>
</form>
</body>
</html>
main.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
欢迎
{{ request.session.currentUserName }}
</body>
</html>
结果:
输入错误的信息:
注:提交后跳转到login,通过写好的用户名和密码判断是否正确
输入正确账号:
同时服务器返回set-cookies信息,包括内置的sessionid以及设置的remember_me
5.4Session与Cookie的区别
1、数据存储位置:cookie 数据存放在客户的浏览器上,session 数据放在服务器上
2、安全性:cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session
3、服务器性能:session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性 能方面,应当使用cookie
4、数据大小:单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie
5、信息重要程度:可以考虑将用户信息等重要信息存放为session,其他信息如果需要保留,可以放在cookie中
6.Django5文件上传实现
文件上传功能是网站开发或者业务系统常见的功能之一
其上传原理都是将文件以二进制的数据格式读取并写入网站或者业务系统指定的目录里
首先在templates模板下新建upload.html,前端上传文件模版页面:
在views里定义to_upload方法实现跳转文件页面:
在views里定义upload方法实现文件上传处理:
在urls里添加映射:
结果:
- 文件对象myFile提供一下属性来获取文件信息:
-
myFile.name:获取上传文件的文件名,包含文件后缀名。
-
myFile.size:获取上传文件的文件大小。
-
myFile.content_type:获取文件类型,通过后续名判断文件类型。
-
- 从文件对象myFile获取文件内容,Django提供了以下读取方式,每种方式说明如下:
-
myFile.read():从文件对象里读取整个文件上传的数据,这个方法只适合小文件。
-
myFile.chunks():按流式响应方式读取文件,在for 循环中进行迭代,将大文件分块写入服务器所指定的保存位置。
-
myFile.multiple_chunks():判断文件对象的文件大小,返回True或者False,当文件大于2.5MB(默认值为2.5MB)时,该方法返回True,否则返回False。因此,可以根据该方法来选择选用read方法读取还是采用chunks方法。
-
7.Django5列表视图ListView
为了实现快速开发,Django提供了视图类功能,封装了视图开发常用的代码,这种基于类实现的响应与请求称为CBV ( Class Base Views)
列表视图ListView,该视图类可以将数据库表的数据以列表的形式显示到页面,常用于数据的查询和展示。
7.1数据库建立
首先为了得到数据库数据,通过定义模型,来映射数据库表;
在项目下创建models.py文件
定义Student类
通过manage.py 中的makemireations生成数据库迁移文件(类似模型类的迁移类,主要是描述了数据表结构的类文件)
注:这里用视频课件的截图,因为我已经创建过了,嫌麻烦
通过manage.py 中的migrate执行迁移文件,同步到数据库中
注:通过class_Meta: db_table = t_student’指明数据库表名
插入测试数据:
insert into t_student VALUES(null,'张三1',20);
insert into t_student VALUES(null,'张三2',21);
insert into t_student VALUES(null,'张三3',22);
insert into t_student VALUES(null,'张三4',23);
insert into t_student VALUES(null,'张三5',24);
insert into t_student VALUES(null,'张三6',25);
insert into t_student VALUES(null,'张三7',26);
insert into t_student VALUES(null,'张三8',27);
insert into t_student VALUES(null,'张三9',28);
insert into t_student VALUES(null,'张三10',29);
insert into t_student VALUES(null,'张三11',30);
insert into t_student VALUES(null,'张三12',31);
数据库:
7.2列表建立
使用ListView,需要继承并设置一些属性
以下是常用属性:
model
:指定要使用的模型。
template_name
:指定要使用的模板名称。
context_object_name
:指定上下文变量名称,默认为 object_list。
paginate_by
:指定分页大小。
extra_context
:设置模型外的数据
也可以重写ListView中的方法以进行自定义
以下是常见方法:
get_queryset()
:返回要在视图中使用的查询集合。这里可以对查询集合进行筛选、排序等操作。
get_context_data()
:返回要在模板上下文中使用的变量。这里可以添加额外的变量,如表单、过滤器等。
在模版页面,Django 提供了分页的功能:
Paginator
和Page
类都是用来做分页的。
# Paginator常用属性和方法
1.`count`: 总共有多少条数据
2.`num_pages`: 总共有多少页
3.`page_range`:页面的区间。比如有三页,那么就是```range``(``1``,``4``)`
# Page常用属性和方法:
1.`has_next`: 是否还有下一页。
2.`has_previous`: 是否还有上一页。
3.`next_page_number`: 下一页的页码。
4.`previous_page_number`: 上一页的页码。
5.`number`: 当前页。
6.`start_index`: 当前页的第一条数据的索引值。
7.`end_index`: 当前页的最后一条数据的索引值。
在urls里添加映射:
在templates下创建student目录,再新建list.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ title }}</title>
</head>
<body>
<table border="1">
<tr>
<td>编号</td>
<td>姓名</td>
<td>年龄</td>
</tr>
<tr>
{% for student in student_list %}
<tr>
<td>{{ student.id }}</td>
<td>{{ student.name }}</td>
<td>{{ student.age }}</td>
</tr>
{% endfor %}
</tr>
</table>
<br>
{% if is_paginated %}
{% if page_obj.has_previous %}
<a href="/student/list?page={{ page_obj.previous_page_number }}">上一页</a>
{% endif %}
{% for current in paginator.page_range %}
{% if current == page_obj.number %}
<a href="/student/list?page={{ current }}"><b><font color="blue">{{ current }}</font></b></a>
{% else %}
<a href="/student/list?page={{ current }}">{{ current }}</a>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<a href="/student/list?page={{ page_obj.next_page_number }}">下一页</a>
{% endif %}
{% endif %}
</body>
</html>
结果:
表格下的页码是通过html的代码进行添加的
上一页:
{% if page_obj.has_previous %}
<a href="/student/list?page={{ page_obj.previous_page_number }}">上一页</a>
{% endif %}
页码:
{% for current in paginator.page_range %}
{% if current == page_obj.number %}
<a href="/student/list?page={{ current }}"><b><font color="blue">{{ current }}</font></b></a>
{% else %}
<a href="/student/list?page={{ current }}">{{ current }}</a>
{% endif %}
{% endfor %}
下一页:
{% if page_obj.has_next %}
<a href="/student/list?page={{ page_obj.next_page_number }}">下一页</a>
{% endif %}
7.3.Django5详细视图DetailView
DetailView多用于展示某一个具体数据对象的详细信息的页面
使用DetailView,需要指定要使用的模型和对象的唯一标识符,并可以自定义其他一些属性,例如模型名称、模板名称、上下文数据等。
以下是DetailView的一些常见属性和方法:
-
-
model:指定要使用的模型。
-
queryset:指定要使用的查询集,用于获取对象。如果未指定,则将使用模型的默认查询集。
-
pk_url_kwarg:指定URL中用于获取对象的唯一标识符的参数名称,默认为’pk’。
-
context_object_name:指定将对象传递给模板时的上下文变量名称,默认为’model’。
-
template_name:指定要使用的模板的名称。
-
get_object(queryset=None):获取要展示的对象。可以重写这个方法来自定义获取对象的逻辑。
-
-
get_context_data(kwargs):返回要传递给模板的上下文数据。你可以重写这个方法来自定义上下文数据。
-
get():处理GET请求的方法,根据配置的对象获取规则执行对象获取和展示逻辑。
-
dispatch(request, *args, **kwargs):处理请求的入口方法,根据请求的不同方法(GET、POST等)执行相应的处理逻辑。
-
DetailView是Django框架中的一个便捷的通用视图,用于展示单个对象的详细信息,并提供了一些有用的属性和方法来简化对象展示逻辑
通过重新设置model属性来指定需要获取的Model类,默认对象名称为object,也可以通过重新设置context_object_name属性来更改这个名字。
在viwes中创建Detail类
在templates下的student目录创建detail页面
在urls中添加一个映射:
在list.html里添加操作项和跳转链接:
结果:
7.4Django5新增视图CreateView
视图类CreateView是对模型新增数据的视图类,是在表单视图类FormView 的基础上加以封装的(就是在视图类FormView的基础上加入数据新增的功能 )
所有涉及到表单视图的功能开发,都需要定义form表单类:
在项目下传教forms.py文件,新建StudentForm类
from django import forms
from django.forms import ModelForm
from Helloworld.models import Student
# 定义学生form表单
class StudentForm(ModelForm):
class Meta: # 配置中心
model = Student # 导入model
fields = '__all__' # 代表所有字段
# fields = ['name'] # 代表某些字段
widgets = {
'name': forms.TextInput(attrs={'id': 'name', 'class': 'inputClass'}),
'age': forms.TextInput(attrs={'id': 'age'}),
}
# 指定标签
labels = {
'name': '姓名',
'age': '年龄'
}
widgets:加id和class,辅助script,labels:修改显示的文字
在view中创建Create类,继承CreateView:
在student目录下新建create页面:
在urls中添加映射:
在list页面中添加新增学生链接:
结果:
7.5Django5修改视图UpdateView
视图类UpdateView是在视图类FormView和视图类DetailView的基础上实现的,它首先使用视图类 DetailView的功能(功能核心类是SingleObjectMixin),通过路由变量查询数据表某条数据并显示在网页上,然后在视图类FormView的基础上,通过表单方式实现数据修改。
在view中新建Update类:
在student目录中创建update页面:
在urls里添加映射:
在list页面中添加操作项:
结果:
7.6Django5删除视图DeleteView
视图类DeleteView的使用方法与视图类UpdateView类似,视图类DeleteView只能删除单条数据,路由变量为模型主键提供查询范围,因为模型主键具有唯一性,所以通过主键查询能精准到某条数据。
查询出来的数据通过POST 请求实现数据删除。
在view中创建Delete类:
在student目录下创建delete页面:
在urls中添加映射:
在list中添加操作项:
结果: