来源引用网络知识与某站曹老师视频相互结合学习记录,仅供参考!
Django 视图定义与使用
Django 视图定义
视图(Views)是 Django 的 MTV 架构模式的 V 部分,主要负责处理用户请求和生成相应的响应内容,然后在页面或其他类型文档中显示。
MTV 架构
Django的MTV分别代表:
- Model(模型):业务对象与数据库的对象(ORM ),比如说是"学生"模型,对应数据库会有一个表;
- Template(模版):负责如何把页面展示给用户;是要写模板代码的,例如"网页"或者展示一个列表、图片等;
- View(视图):负责业务逻辑,并在适当的时候调用Model和Template;类似控制器,就像管理员是核心控制;
此外,Django还有一个urls分发器,它的作用是将一个URI的页面请求分发给不同的view处理,view再调用相应的Model和Template。 Django WEB框架示意图如下所示:
Django 设置视图响应状态
客户端请求后端服务,在 view.py 视图层方法最终 return 返回视图响应;Python 内置提供看响应类型,来实现不同的返回不同的 HTTP 状态码;
|------------------------------------|---|---|
| 响应类型 | 解释说明 ||
| HttpResponse('Hello world'") | 状态码200,请求已成功被服务器接收。 ||
| HttpResponseRedirect('/') | 状态码302,重定向首页地址。 ||
| HttpResponsePermanentRedirect('/') | 状态码301,永久重定向首页地址。 ||
| HttpResponseBadRequest("'400') | 状态码400,访问的页面不存在或请求错误(有些是格式错误)。 ||
| HttpResponseForbidden('403') | 状态码403,是拒绝,没有访问权限。 ||
| HttpResponseNotFound('404") | 状态码404,网页不存在或网页的URL失效。 ||
| HttpResponseNotAllowed('405') | 状态码405,不允许使用该请求方式。 ||
| HttpResponseServerError('500'") | 状态码500,服务器内容错误。 ||
| JsonResponse( {'foo' : 'bar'}) | 默认状态码200,响应内容为JSON数据。 ||
| StreamingHttpResponse() | 默认状态码200,响应内容以流式输出。 ||
举例说明
HttpResponse
1、修改"djangoProject"项目"helloWorld"应用下的"views.py "配置文件中的"index"函数方法,浏览器输入"http://127.0.0.1:8000/index/"测试验证;
# 导包
from django.http import HttpResponse
from django.shortcuts import render, redirect
# Create your views here.
# 自定义一个index方法,里面要加上request请求对象
def index(request):
# 自定义一个html,一个font标签和网址推广
html = "<font color='red'>百度一下,上www.baidu.com</font>"
# HttpResponse()第一个参数要放的是内容,status默认就是200
return HttpResponse(html, status=200)
# return返回 render渲染(第一个参数首先渲染时要带上一个request请求,第二个参数是模板文件)
# return render(request, 'index.html')
# 定义index_id方法,里面第一个参数request请求对象,第二个参数 id
def index_id(request, id):
# 判断 id是否为0
if id == 0:
# 导包引入redirect模块,如果id等于0的话,重定向到一个目标静态地址
return redirect("/static/error.html")
else:
# 使用HttpResponse直接返回内容--因为id是int类型,里面得使用str()进行转换
return HttpResponse("id是" + str(id) + "的某某平台系统页面")
# 定义index_id方法,第一个参数request请求对象,里面继续跟多个路由变量"year, month, day, id"
def index_id02(request, year, month, day, id):
# 使用HttpResponse直接返回内容--因为id是int类型,里面得使用str()进行转换
return HttpResponse(str(year) + "/" + str(month) + "/" + str(day) + "/" +"id是" + str(id) + "的某某平台系统页面")
# 定义index_id方法,第一个参数request请求对象,后面跟多个路由变量"year, month, day"--注意,使用正则后不能与"id"再混合使用了
def index_id03(request, year, month, day):
# 使用HttpResponse直接返回内容--因为id是int类型,里面得使用str()进行转换
return HttpResponse(str(year) + '/' + str(month) + '/' + str(day) + "使用正则路由后的某某平台系统页面")

请求测试,状态码200,返回网页信息;status=200不写的话默认也是200;
HttpResponseNotFound('404")
2、修改"djangoProject"项目"helloWorld"应用下的"views.py "配置文件中的"index"函数方法,浏览器输入"http://127.0.0.1:8000/index/"测试验证;导包引入"HttpResponseNotFound"模块,若HttpResponseNotFound() 里面没有输入任何内容,正常提示"找不到 XXXX 的网页,如若HttpResponseNotFound("Not Found")里面有填写显示内容,则显示指定填写内容;
def index(request):
return HttpResponseNotFound()

JsonResponse( {'message': 'Hello World!'}) 响应 json 数据
3、修改"djangoProject"项目"helloWorld"应用下的"views.py "配置文件中的"index"函数方法,浏览器输入"http://127.0.0.1:8000/index/"测试验证;导包引入"JsonResponse"模块,修改完成代码后刷新浏览器网页再次请求测试,返回状态码200,返回json格式数据;
def index(request):
return JsonResponse({'message': 'Hello World!'})

高级实现 HttpResponse 引入模板的概念
上面的 HttpResponse 示例,简单网页直接可以响应到页面,但是如果它是一个比较复杂网页,就会增加视图函数的代码量;所以需要引入模版的概念,通过 Django 提供的 render方法渲染数据到模版,然后再响应到页面;
def index(request):
# return返回 render渲染(第一个参数首先渲染时要带上一个request请求,第二个参数是模板文件)
return render(request, 'index.html')
鼠标悬停在"render"上后可查看其用法,或者先按住"ctrl"键再单击对应的方法名,可查看详细源码介绍;经过模版渲染后得到content网页内容,依然返回的是HttpResponse对象。

request 和 template_name 是必填参数,其他参数是可选;
- request:浏览器向服务器发送的请求对象,包含用户信息、请求内容和请求方式等;
- template_name:设置模板文件名,用于生成网页内容;
- context:对模板上下文(模板变量)赋值,以字典格式表示,默认情况下是一个空字典;
- content_type:响应内容的数据格式,一般情况下使用默认值即可;
- status:HTTP状态码,默认为200;一般也不用写;
- using:设置模板引擎,用于解析模板文件,生成网页内容;默认的就是Django 模板引擎;
这些参数一般都空着即可,最多是使用前面三个参数;
带context 参数
4、修改"djangoProject"项目"helloWorld"应用下的"views.py "配置文件中的"index"函数方法,写一个带字典参数的render渲染模版实例;
def index(request):
content_value = {"content_msg": "百度一下,搜索 www.baidu.com"}
return render(request, 'index.html',context=content_value)

5、修改"helloWorld"应用"templates"目录文件路径下"index.html"文件内容,语法使用两个大括号来通过 key 来取值;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title Is Django Hello World index2</title>
</head>
<body>
模板取值(语法是两个大括号/花括号):{{ content_msg }}
<h1>定义一个h1大标题"index2"</h1>
<p>定义一个段落"index2"</p>
<h2>h2标题"index2" Django Hello World</h2>
<p>又是一个段落;"index2"然后下面是一张图片。</p>
<img src="https://www.runoob.com/wp-content/uploads/2015/01/admin1.png" width="304" height="228" alt=""/>
<br>
<a href="https://www.runoob.com/html/html-tutorial.html">这是一个"HTML 教程 index2"链接</a>
</body>
</html>
模版代码改写下,模版里取值语法 {{ 字典的key值 }}

测试验证模板取值,能够成功获取到数据信息;

Django 设置重定向响应
在上一篇文章中有介绍到通过"引入RedirectView 模块,使用RedirectView.as_view()方法来进行 URL 的重定向使用",这种形式方便且书写简单,但是不太灵活,在实际开发过程中,为了能否实现业务上的判断,来进行业务重定向跳转,需要使用"redirect"方法;
网站方面重定向的状态码分为301和302,其中 301 是永久性跳转的,而 302 是临时跳转的,两者的区别在于搜索引擎的网页抓取;301重定向是永久的重定向,搜索引擎在抓取新内容的同时会将旧的网址替换为重定向之后的网址;302跳转是暂时的跳转,搜索引擎会抓取新内容而保留旧的网址;因为服务器 返回302代码,所以搜索引擎认为新的网址只是暂时的;Django内置提供了两个重定向实现类,一个是"HttpResponseRedirect",代表HTTP状态码302;另一个是"HttpResponsePermanentRedirect",代表HTTP状态码301;

测试重定向
临时性跳转
6、在项目"static"目录文件路径下新建一个名称为"new"的 HTML 文件,简单输入内容以便区分;

7、修改"djangoProject"项目"helloWorld"应用下的"views.py "配置文件中的"index"函数方法,然后请求 index 测试是否能够跳转;
def index(request):
# 直接return--redirect里面第一个参数就是跳转到哪里去,支持三种方式,这里使用最简单的一个url
return redirect('/static/new.html')

redirect 里面第一个参数就是跳转到哪里去,支持三种方式,第一种方式是一个"A model"模板,第二种是"A view name"视图名称(路由名称),在复杂的业务情况下也可以使用路由名称,第三种方式就是最简单的"A URL"一个 URL 即可;第二个参数暂时不用;

通过查看redirect方法的源码可知,它要"redirect_class"构造"return"返回的一个类型是什么,主要是判断"permanent",如果是永久性的话,就使用"HttpResponsePermanentRedirect",否则的话则是使用"HttpResponseRedirect";
class HttpResponseRedirect(HttpResponseRedirectBase):
status_code = 302
class HttpResponsePermanentRedirect(HttpResponseRedirectBase):
status_code = 301
第一个跳转参数支持模型 ,视图路由名称,还有最常用得url地址;第二个参数就是是否永久跳转,默认Flase;redirect_class 通过 permanent 判断,true返回 HttpResponsePermanentRedirect,false 则返回HttpResponseRedirect。
8、运行项目,浏览器输入"http://127.0.0.1:8000/index/"测试查看(建议使用浏览器无痕模式,这样不会有缓存干扰测试,其实无痕浏览器也是存在缓存的);成功打开"new新页面",它会跳转到"/static/new.html";打开网页开发者工具,发起 index 请求,可以看到默认的是一个临时的跳转 302;

永久性跳转
假如说要进行永久性的跳转;
9、继续使用 redirect 方法里面的第二个参数,加上"permanent=True"第二个参数permanent 默认为False;
def index(request):
# 直接return--redirect里面第一个参数就是跳转到哪里去,支持三种方式,这里使用最简单的一个url;第二个参数修改为True
return redirect('/static/new.html', permanent=True)
10、再次浏览器输入"http://127.0.0.1:8000/index/"测试查看,已经从刚才的 302 变成为 301 Moved Permanently 了;

redirect 方法里面只要是 URL 地址都是可以的,不单单只是静态的,只要是地址,它都能跳转;
11、修改"djangoProject"应用下的"urls.py "配置文件内容;
"""
URL configuration for djangoProject project.
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/5.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.conf import settings
from django.contrib import admin
from django.urls import path, re_path, include
from django.views.generic import RedirectView
from django.views.static import serve
import helloWorld.views
urlpatterns = [
path('admin/', admin.site.urls),
# 可直接复制上面"admin",把"admin"修改为"index";后面是跟的"处理函数helloWorld.views.index"
# 是helloWorld应用的views里面的index()--引入helloWorld.views,记得index后不能加小括号,因为传入的是对象;
path('index/', helloWorld.views.index),
# 要是请求"redirectTo"这个请求的话给重定向到"index"--重定向使用RedirectView.as_view(),里面使用关键词参数url
path('redirectTo', RedirectView.as_view(url="index/")),
# 自定义名称,例如叫"index_id/",后面再跟上某网页id;<int:id> int指定类型,路由变量为id;对应对应的路由映射
path('index_id/<int:id>', helloWorld.views.index_id),
# 多个路由变量
path('index_id02/<int:year>/<int:month>/<int:day>/<int:id>', helloWorld.views.index_id02),
# 正则表达式匹配是必须使用re_path方法,正则表达式"?P"开头是固定格式
re_path('index_id03/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})', helloWorld.views.index_id03),
# 配置媒体文件的路由地址
re_path('media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}, name='media'),
# 命名空间namespace--比如说是"user/"开头的,第一个参数include(),第二个参数namespace
# 导包引入include模块,include()里面也有两个参数,第一个是指定user的urls,第二个是项目名;
path('user/', include(('user.urls', 'user'), namespace='user')),
path('order/', include(('order.urls', 'order'), namespace='order'))
]
12、修改"djangoProject"项目"helloWorld"应用下的"views.py "配置文件中的"index"函数方法,测试临时性跳转到指定的页面;
# 导包
from django.http import HttpResponse, HttpResponseNotFound, JsonResponse
from django.shortcuts import render, redirect
# Create your views here.
# 自定义一个index方法,里面要加上request请求对象
def index(request):
# 直接return--redirect里面第一个参数就是跳转到哪里去,支持三种方式,这里使用最简单的一个url
# return redirect('/static/new.html', permanent=True)
# 例如:临时性跳转到/index_id/5211314页面
return redirect('/index_id/5211314')
# 定义index_id方法,里面第一个参数request请求对象,第二个参数 id
def index_id(request, id):
# 判断 id是否为0
if id == 0:
# 导包引入redirect模块,如果id等于0的话,重定向到一个目标静态地址
return redirect("/static/error.html")
else:
# 使用HttpResponse直接返回内容--因为id是int类型,里面得使用str()进行转换
return HttpResponse("id是" + str(id) + "的某某平台系统页面")
# 定义index_id方法,第一个参数request请求对象,里面继续跟多个路由变量"year, month, day, id"
def index_id02(request, year, month, day, id):
# 使用HttpResponse直接返回内容--因为id是int类型,里面得使用str()进行转换
return HttpResponse(str(year) + "/" + str(month) + "/" + str(day) + "/" +"id是" + str(id) + "的某某平台系统页面")
# 定义index_id方法,第一个参数request请求对象,后面跟多个路由变量"year, month, day"--注意,使用正则后不能与"id"再混合使用了
def index_id03(request, year, month, day):
# 使用HttpResponse直接返回内容--因为id是int类型,里面得使用str()进行转换
return HttpResponse(str(year) + '/' + str(month) + '/' + str(day) + "使用正则路由后的某某平台系统页面")

13、清空浏览器缓存或者重新打开另外的浏览器,地址栏输入"http://127.0.0.1:8000/index/"测试查看是能够成功跳转的,所以说无论是静态地址还是动态地址,只要是地址都能够跳转。

Django 二进制文件下载响应
响应内容除了返回网页信息外,还可以实现文件下载功能,是网站常用的功能之一。
下载文件的实现
Django提供三种方式实现文件下载功能;
- HttpResponse 是所有响应过程的核心类,它的底层功能类是HttpResponseBase;它是最简单最基本的,适合非常小的文件,可以直接使用 HttpResponse;
- StreamingHttpResponse 是在 HttpResponseBase的基础上进行继承与重写的,是基于 HttpResponse 进行封装的,它实现流式响应输出(流式响应输出是使用Python的迭代器将数据进行分段处理并传输的),适合比较复杂情况的大文件,适用于大规模数据响应和文件传输响应;
- FileResponse 是在StreamingHttpResponse 的基础上进行继承与重写的,它实现文件的流式响应输出,只适用于文件传输响应;如果是文件,使用 FileResponse 就行了;
实例应用
准备一个 20M 左右大小的二进制文件,文件格式不限制"文本、图像、音频、视频、exe 可执行文件、压缩文件等等"格式的都行,只要是二进制文件就行;准备好二进制文件之后,自行把它放在某个文件路径下,例如:把一个压缩文件放到 D 盘根目录下(烦请自行设置,这里仅为演示左右);
HttpResponse
14、修改"djangoProject"项目"helloWorld"应用下的"views.py "配置文件内容;
# 导包
from django.http import HttpResponse, HttpResponseNotFound, JsonResponse
from django.shortcuts import render, redirect
# Create your views here.
# 自定义一个index方法,里面要加上request请求对象
def index(request):
# 直接return--redirect里面第一个参数就是跳转到哪里去,支持三种方式,这里使用最简单的一个url
# return redirect('/static/new.html', permanent=True)
# 例如:临时性跳转到/index_id/5211314页面
return redirect('/index_id/5211314')
# 定义index_id方法,里面第一个参数request请求对象,第二个参数 id
def index_id(request, id):
# 判断 id是否为0
if id == 0:
# 导包引入redirect模块,如果id等于0的话,重定向到一个目标静态地址
return redirect("/static/error.html")
else:
# 使用HttpResponse直接返回内容--因为id是int类型,里面得使用str()进行转换
return HttpResponse("id是" + str(id) + "的某某平台系统页面")
# 定义index_id方法,第一个参数request请求对象,里面继续跟多个路由变量"year, month, day, id"
def index_id02(request, year, month, day, id):
# 使用HttpResponse直接返回内容--因为id是int类型,里面得使用str()进行转换
return HttpResponse(str(year) + "/" + str(month) + "/" + str(day) + "/" +"id是" + str(id) + "的某某平台系统页面")
# 定义index_id方法,第一个参数request请求对象,后面跟多个路由变量"year, month, day"--注意,使用正则后不能与"id"再混合使用了
def index_id03(request, year, month, day):
# 使用HttpResponse直接返回内容--因为id是int类型,里面得使用str()进行转换
return HttpResponse(str(year) + '/' + str(month) + '/' + str(day) + "使用正则路由后的某某平台系统页面")
# 定义目标文件路径
file_path = "D:\\works\\djangoProject\\datas\\IDM.rar"
# 定义download_file1下载方法,请求需要带上request(所有的请求都要带上request)
def download_file1(request):
# 定义文件--使用open函数方法以"rb"二进制读取模式打开文件--然后返回一个file文件对象
file = open(file_path, 'rb')
# 创建构造好了HttpResponse对象之后返回给response
response = HttpResponse(file)
return response

15、修改"djangoProject"应用下的"urls.py "配置文件内容,配置"download_file"对应的数据信息,定义映射关系;
"""
URL configuration for djangoProject project.
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/5.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.conf import settings
from django.contrib import admin
from django.urls import path, re_path, include
from django.views.generic import RedirectView
from django.views.static import serve
import helloWorld.views
urlpatterns = [
path('admin/', admin.site.urls),
# 可直接复制上面"admin",把"admin"修改为"index";后面是跟的"处理函数helloWorld.views.index"
# 是helloWorld应用的views里面的index()--引入helloWorld.views,记得index后不能加小括号,因为传入的是对象;
path('index/', helloWorld.views.index),
# 要是请求"redirectTo"这个请求的话给重定向到"index"--重定向使用RedirectView.as_view(),里面使用关键词参数url
path('redirectTo', RedirectView.as_view(url="index/")),
# 自定义名称,例如叫"index_id/",后面再跟上某网页id;<int:id> int指定类型,路由变量为id;对应对应的路由映射
path('index_id/<int:id>', helloWorld.views.index_id),
# 多个路由变量
path('index_id02/<int:year>/<int:month>/<int:day>/<int:id>', helloWorld.views.index_id02),
# 正则表达式匹配是必须使用re_path方法,正则表达式"?P"开头是固定格式
re_path('index_id03/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})', helloWorld.views.index_id03),
# 配置媒体文件的路由地址
re_path('media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}, name='media'),
# 命名空间namespace--比如说是"user/"开头的,第一个参数include(),第二个参数namespace
# 导包引入include模块,include()里面也有两个参数,第一个是指定user的urls,第二个是项目名;
path('user/', include(('user.urls', 'user'), namespace='user')),
path('order/', include(('order.urls', 'order'), namespace='order')),
# 配置 download_file1
path('download1/', helloWorld.views.download_file1)
]

16、为了方便测试,在浏览器中测试并不太合适;在项目"static"目录文件路径下新建一个名称为"download"的 HTML 静态文件,简单输入一个超链接内容;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="/download1">下载测试一:HttpResponse</a><br>
</body>
</html>

17、运行项目测试验证,浏览器输入"http://127.0.0.1:8000/static/download.html"测试查看,点击"下载测试一:HttpResponse"开始下载,发现有问题,实际并不能下载成功,单击下载后有返回数据,但是需要以"附件"形式,需要进一步处理;

18、修改优化"djangoProject"项目"helloWorld"应用下的"views.py "配置文件内容,指定文件类型并以附件的形式下载;
# 导包
from django.http import HttpResponse, HttpResponseNotFound, JsonResponse
from django.shortcuts import render, redirect
# Create your views here.
# 自定义一个index方法,里面要加上request请求对象
def index(request):
# 直接return--redirect里面第一个参数就是跳转到哪里去,支持三种方式,这里使用最简单的一个url
# return redirect('/static/new.html', permanent=True)
# 例如:临时性跳转到/index_id/5211314页面
return redirect('/index_id/5211314')
# 定义index_id方法,里面第一个参数request请求对象,第二个参数 id
def index_id(request, id):
# 判断 id是否为0
if id == 0:
# 导包引入redirect模块,如果id等于0的话,重定向到一个目标静态地址
return redirect("/static/error.html")
else:
# 使用HttpResponse直接返回内容--因为id是int类型,里面得使用str()进行转换
return HttpResponse("id是" + str(id) + "的某某平台系统页面")
# 定义index_id方法,第一个参数request请求对象,里面继续跟多个路由变量"year, month, day, id"
def index_id02(request, year, month, day, id):
# 使用HttpResponse直接返回内容--因为id是int类型,里面得使用str()进行转换
return HttpResponse(str(year) + "/" + str(month) + "/" + str(day) + "/" +"id是" + str(id) + "的某某平台系统页面")
# 定义index_id方法,第一个参数request请求对象,后面跟多个路由变量"year, month, day"--注意,使用正则后不能与"id"再混合使用了
def index_id03(request, year, month, day):
# 使用HttpResponse直接返回内容--因为id是int类型,里面得使用str()进行转换
return HttpResponse(str(year) + '/' + str(month) + '/' + str(day) + "使用正则路由后的某某平台系统页面")
# 定义目标文件路径
file_path = "D:\\works\\djangoProject\\datas\\IDM.rar"
# 定义download_file1下载方法,请求需要带上request(所有的请求都要带上request)
def download_file1(request):
# 定义文件--使用open函数方法以"rb"二进制读取模式打开文件--然后返回一个file文件对象
file = open(file_path, 'rb')
# 创建构造好了HttpResponse对象之后返回给response
response = HttpResponse(file)
# 指定文件类型
response['Content-Type'] = 'application/rar-compressed'
# 扩展--指定附件及文件名字(可以动态拼接filename,并不建议使用原始名称)
response['Content-Disposition'] = 'attachment; filename=file1.rar'
return response

19、重新打开浏览器输入"http://127.0.0.1:8000/static/download.html"访问,点击"下载测试一:HttpResponse"开始下载,可以看到能够以附件文件名"file1.rar"下载;

StreamingHttpResponse 和 FileResponse
StreamingHttpResponse 会比HttpResponse 更加强大一点,StreamingHttpResponse 是流式分段的,比较适合大量的大文件;
FileResponse 是比较适用专门的文件,如是目标就是文件的 话,直接使用 FileResponse 是最快速最快捷的;
20、修改"djangoProject"项目"helloWorld"应用下的"views.py "配置文件内容;
# 导包
from django.http import HttpResponse, HttpResponseNotFound, JsonResponse, StreamingHttpResponse, FileResponse
from django.shortcuts import render, redirect
# Create your views here.
# 自定义一个index方法,里面要加上request请求对象
def index(request):
# 直接return--redirect里面第一个参数就是跳转到哪里去,支持三种方式,这里使用最简单的一个url
# return redirect('/static/new.html', permanent=True)
# 例如:临时性跳转到/index_id/5211314页面
return redirect('/index_id/5211314')
# 定义index_id方法,里面第一个参数request请求对象,第二个参数 id
def index_id(request, id):
# 判断 id是否为0
if id == 0:
# 导包引入redirect模块,如果id等于0的话,重定向到一个目标静态地址
return redirect("/static/error.html")
else:
# 使用HttpResponse直接返回内容--因为id是int类型,里面得使用str()进行转换
return HttpResponse("id是" + str(id) + "的某某平台系统页面")
# 定义index_id方法,第一个参数request请求对象,里面继续跟多个路由变量"year, month, day, id"
def index_id02(request, year, month, day, id):
# 使用HttpResponse直接返回内容--因为id是int类型,里面得使用str()进行转换
return HttpResponse(str(year) + "/" + str(month) + "/" + str(day) + "/" +"id是" + str(id) + "的某某平台系统页面")
# 定义index_id方法,第一个参数request请求对象,后面跟多个路由变量"year, month, day"--注意,使用正则后不能与"id"再混合使用了
def index_id03(request, year, month, day):
# 使用HttpResponse直接返回内容--因为id是int类型,里面得使用str()进行转换
return HttpResponse(str(year) + '/' + str(month) + '/' + str(day) + "使用正则路由后的某某平台系统页面")
# 定义目标文件路径
file_path = "D:\\works\\djangoProject\\datas\\IDM.rar"
# 定义download_file1下载方法,请求需要带上request(所有的请求都要带上request)
def download_file1(request):
# 定义文件--使用open函数方法以"rb"二进制读取模式打开文件--然后返回一个file文件对象
file = open(file_path, 'rb')
# 创建构造好了HttpResponse对象之后返回给response
response = HttpResponse(file)
# 指定文件类型
response['Content-Type'] = 'application/rar-compressed'
# 扩展--指定附件及文件名字(可以动态拼接filename,并不建议使用原始名称)
response['Content-Disposition'] = 'attachment; filename=file1.rar'
return response
def download_file2(request):
file = open(file_path, 'rb')
# 创建构造好了StreamingHttpResponse对象之后返回给response
response = StreamingHttpResponse(file)
response['Content-Type'] = 'application/rar-compressed'
response['Content-Disposition'] = 'attachment; filename=file2.rar'
return response
def download_file3(request):
file = open(file_path, 'rb')
# 创建构造好了FileResponse对象之后返回给response
response = FileResponse(file)
response['Content-Type'] = 'application/rar-compressed'
response['Content-Disposition'] = 'attachment; filename=file3.rar'
return response

21、修改"djangoProject"应用下的"urls.py "配置文件内容,配置"download_file"对应的数据信息,定义下映射关系;
"""
URL configuration for djangoProject project.
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/5.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.conf import settings
from django.contrib import admin
from django.urls import path, re_path, include
from django.views.generic import RedirectView
from django.views.static import serve
import helloWorld.views
urlpatterns = [
path('admin/', admin.site.urls),
# 可直接复制上面"admin",把"admin"修改为"index";后面是跟的"处理函数helloWorld.views.index"
# 是helloWorld应用的views里面的index()--引入helloWorld.views,记得index后不能加小括号,因为传入的是对象;
path('index/', helloWorld.views.index),
# 要是请求"redirectTo"这个请求的话给重定向到"index"--重定向使用RedirectView.as_view(),里面使用关键词参数url
path('redirectTo', RedirectView.as_view(url="index/")),
# 自定义名称,例如叫"index_id/",后面再跟上某网页id;<int:id> int指定类型,路由变量为id;对应对应的路由映射
path('index_id/<int:id>', helloWorld.views.index_id),
# 多个路由变量
path('index_id02/<int:year>/<int:month>/<int:day>/<int:id>', helloWorld.views.index_id02),
# 正则表达式匹配是必须使用re_path方法,正则表达式"?P"开头是固定格式
re_path('index_id03/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})', helloWorld.views.index_id03),
# 配置媒体文件的路由地址
re_path('media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}, name='media'),
# 命名空间namespace--比如说是"user/"开头的,第一个参数include(),第二个参数namespace
# 导包引入include模块,include()里面也有两个参数,第一个是指定user的urls,第二个是项目名;
path('user/', include(('user.urls', 'user'), namespace='user')),
path('order/', include(('order.urls', 'order'), namespace='order')),
# 配置 download_file
path('download1/', helloWorld.views.download_file1),
path('download2/', helloWorld.views.download_file2),
path('download3/', helloWorld.views.download_file3)
]

22、修改项目"static"目录文件路径下"download.html"文件内容,添加StreamingHttpResponse 和 FileResponse内容;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>下载测试</title>
</head>
<body>
<a href="/download1">下载测试一:HttpResponse</a><br>
<a href="/download2">下载测试二:StreamingHttpResponse</a><br>
<a href="/download3">下载测试三:FileResponse</a>
</body>
</html>

23、测试验证,StreamingHttpResponse 和 FileResponse 都能够下载成功。

未完待续......
