Django - 视图函数
视图函数,或简称视图,是一种接受 Web 请求并返回 Web 响应的 Python 函数。 这个响应可以是网页的 HTML 内容,也可以是重定向,也可以是 404 错误,也可以是 XML 文档,也可以是图像. . . 或任何东西,真的。 视图本身包含返回该响应所需的任意逻辑。 此代码可以位于您想要的任何位置,只要它在您的 Python 路径上即可。 没有其他要求 —— 没有 “魔法”,可以这么说。 为了将代码放在某个地方,约定是将视图放在一个名为 views.py
的文件中,该文件位于您的项目或应用程序目录中。
这里是一个以 HTML 文档形式返回当前日期和时间的视图:
1 | from django.http import HttpResponse |
- 首先,我们从
django.http
模块导入类HttpResponse
,以及 Python 的datetime
库。 - 然后,我们定义一个名为
current_datetime
的函数。这是一个视图函数。每个视图函数都将HttpRequest
对象作为第一个参数,通常名为request
。- 注意:视图函数名称无关紧要;它不需要以特定的名称来让 Django 识别它。我们在这里命名
current_datetime
,因为这个名字可以清楚的表示它的用途。
- 注意:视图函数名称无关紧要;它不需要以特定的名称来让 Django 识别它。我们在这里命名
- 视图返回一个包含生成的响应的
HttpResponse
对象。每个视图函数都要返回HttpResponse
对象。(有例外,我们稍后再讲)
属相
scheme
代表请求协议的字符串(通常是
http
或https
)。path
表示请求页面的完整路径的字符串,不包括方案、域或查询字符串。
method
代表请求中使用的 HTTP 方法的字符串。保证是大写字母。
GET
一个类似字典的对象,包含所有给定的 HTTP GET 参数。参见下面的
QueryDict
文档。POST
一个类似字典的对象,包含所有给定的 HTTP POST 参数,前提是请求包含表单数据。参见下面的
QueryDict
文档。如果你需要访问请求中发布的原始或非表单数据,可以通过HttpRequest.body
属性来访问。COOKIES
一个包含所有 cookies 的字典。键和值是字符串。
FILES
- 一个类似字典的对象,包含所有上传的文件。
FILES
中的每个键是<input type="file" name="">
中的name
。FILES
中的每个值是一个UploadedFile
。更多信息请参见 管理文件。 FILES
只有在请求方法是 POST,并且发布请求的<form>
有enctype="multipart/form-data"
的情况下,才会包含数据。否则,FILES
将是一个类似字典的空白对象。
- 一个类似字典的对象,包含所有上传的文件。
META
一个包含所有可用的 HTTP 头文件的字典。可用的头信息取决于客户端和服务器,部分示例:
CONTENT_LENGTH
—— 请求体的长度(字符串)。CONTENT_TYPE
—— 请求体的 MIME 类型。HTTP_ACCEPT
—— 可接受的响应内容类型。HTTP_ACCEPT_ENCODING
—— 可接受的响应编码。HTTP_ACCEPT_LANGUAGE
—— 可接受的响应语言。HTTP_HOST
—— 客户端发送的 HTTP 主机头。HTTP_REFERER
—— referrer 页面,如果有的话。HTTP_USER_AGENT
—— 客户端的用户代理字符串。QUERY_STRING
—— 查询字符串,是一个单一的(未解析的)字符串。REMOTE_ADDR
—— 客户机的 IP 地址。REMOTE_HOST
—— 客户机的主机名。REMOTE_USER
-- The user authenticated by the web server, if any.REQUEST_METHOD
——"GET"
或"POST"
等字符串。SERVER_NAME
—— 服务器的主机名。SERVER_PORT
—— 服务器的端口(字符串)。
headers
一个不区分大小写的类似字典的对象,提供对请求中所有 HTTP 前缀头的访问(加上
Content-Length
和Content-Type
)。
方法
get_host()
使用
HTTP_X_FORWARDED_HOST
(如果USE_X_FORWARDED_HOST
已启用)和HTTP_HOST
头信息,按顺序返回请求的发起主机。如果它们没有提供一个值,则该方法使用SERVER_NAME
和SERVER_PORT
的组合,详见 PEP 3333。get_port()
使用
HTTP_X_FORWARDED_PORT
(如果USE_X_FORWARDED_PORT
已启用)和SERVER_PORT
META
变量中的信息,按顺序返回请求的起始端口。is_ajax()
- 是否是 ajax 请求,该方法于 Django 3.1 中已被 废弃,因为它依赖于 jQuery 特定的方式来表示 AJAX 调用,而当前的用法倾向于使用 JavaScript Fetch API 。根据你的用例,你可以写你自己的 AJAX 检测方法,或者使用新的
HttpRequest.accepts()
方法,如果你的代码依赖于客户端Accept
HTTP 头。 - 如果你正在编写自己的 AJAX 检测方法,
request.is_ajax()
可以完全复制为request.headers.get('x-requested-with') == 'XMLHttpRequest'
。
- 是否是 ajax 请求,该方法于 Django 3.1 中已被 废弃,因为它依赖于 jQuery 特定的方式来表示 AJAX 调用,而当前的用法倾向于使用 JavaScript Fetch API 。根据你的用例,你可以写你自己的 AJAX 检测方法,或者使用新的
accepts(mime_type)
如果请求的
Accept
头符合mime_type
参数,则返回True
。1
2'text/html') request.accepts(
True
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14from django.http import HttpResponse
def index(request):
print(request.path)
print(request.method)
# print(request.is_ajax())
print(request.accepts('text/html'))
print(request.scheme)
print(request.GET)
print(request.POST)
print(request.FILES)
print(request.get_host())
print(request.META.get('REMOTE_ADDR'))
return HttpResponse('<h1>商品首页面</h1>')
概述
- 与 Django 自动创建的
HttpRequest
对象不同,HttpResponse
对象是你的责任。你写的每个视图都要负责实例化、填充和返回一个HttpResponse
对象。 HttpResponse
类位于django.http
模块中。
- 与 Django 自动创建的
render()
概述
- 将给定的模板与给定的上下文字典组合在一起,并以渲染的文本返回一个
HttpResponse
对象。 - Django 没有提供返回
TemplateResponse
的便捷函数,因为TemplateResponse
的构造函数提供了与render()
同等程度的便利。
- 将给定的模板与给定的上下文字典组合在一起,并以渲染的文本返回一个
参数
示例
1
2
3
4from django.shortcuts import render
def show_goods1(request):
return render(request, 'goods/goods.html')
redirect()
概述
- 返回一个
HttpResponseRedirect
,指向传递参数的适当 URL。 - 参数可以是:
- 一个模型:模型的
get_absolute_url()
函数将被调用。 - 视图名,可能带有的参数:
reverse()
将被用于反向解析名称。 - 一个绝对或相对 URL,将按原样用作重定向位置。
- 一个模型:模型的
- 返回一个
示例
传递对象,对象的
get_absolute_url()
方法将被调用来指向重定向地址1
2
3
4
5
6from django.shortcuts import redirect
def my_view(request):
...
obj = MyModel.objects.get(...)
return redirect(obj)传递视图名和一些可选的位置或关键字参数;URL 将使用
reverse()
方法来反向解析1
2
3
4
5
6
7
8def my_view(request):
...
return redirect('some-view-name', foo='bar')
def login(request):
...
return redirect(reverse('user:show'))
return redirect('user:show')传递绝对或相对 URL 来重定向
1
2
3
4
5
6
7
8
9# 传递相对URL
def my_view(request):
...
return redirect('/some/url/')
# 传递绝对URL
def my_view(request):
...
return redirect('https://example.com/')
默认情况下,
redirect()
返回临时重定向。所有以上形式都接受permanent
参数;如果设置为True
会返回一个永久重定向:1
2
3
4def my_view(request):
...
obj = MyModel.objects.get(...)
return redirect(obj, permanent=True)
reverse()
在主路由上添加
namespace
1
2
3
4
5
6
7
8
9
10# urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path("user/", include("user.urls", namespace="suer")),
]在子路由上添加
name
1
2
3
4
5
6
7
8
9
10
11
12
13# user/urls.py
from django.urls import path
from user.views import *
# 注意:主路由上添加完namespace后会报错,需要在每个子路由中添加app_name
app_name = "user"
urlpatterns = [
path("login/", login, name="login"),
path("show/", show, name="show"),
]使用 reverse
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18# user/views.py
from django.shortcuts import render, redirect
from django.urls import reverse
# Create your views here.
def login(request):
if request.method == 'POST':
return redirect(reverse('user:show'))
# 直接用redirect重定向亦可
return redirect('user:show')
return render(request, 'user/login.html')
def show(request):
users = User.objects.all()
return render(request, 'user/show.html', {'users': users})