视图(View) 是 Django 的 MTV 架构模式的 V 部分,主要负责处理用户请求和生成相应的响应内容,然后在页面或其他类型文档中显示。也可以理解为视图是 MVC 架构里面的 C 部分(控制器),主要处理功能和业务上的逻辑。
构建网页内容
在上一节中,我们看到视图函数都是通过 return
方式返回数据内容的,然后生成相应的网页内容呈现在浏览器.上。而视图函数的 return
具有多种响应类型,如下表所示:
响应类型 | 说明 |
---|---|
HttpResponse('Hello world') | HTTP状态码 200,请求已成功被服务器接收 |
HttpResponseRedirect('/admin/') | HTTP状态码 302,重定向 Admin 站点的 URL |
HttpResponsePermanentRedirect('/admin/') | HTTP状态码 301,永久重定向 Admin 站点的 URL |
HttpResponseBadRequest('BadRequest') | HTTP状态码 400,访问的页面不存在或者请求错误 |
HttpResponseNotFound('NotFound') | HTTP状态码 404,网页不存在或网页的 URL 失效 |
HttpResponseForbidden('NotFound') | HTTP状态码 403,没有访问权限 |
HttpResponseNotAllowed('NotAllowedGet') | HTTP状态码 405,不允许使用该请求方式 |
HttpResponseServerError('ServerError) | HTTP状态码 500,服务器内容错误 |
响应类型代表 HTTP 状态码,其核心作用是 Web Server 服务器用来告诉客户端当前的网页请求发生了什么事,或者当前 Web 服务器的响应状态。上述响应主要来自于模块 django.http
,该模块是实现响应功能的核心。
可以使用该模块生成精美的 HTML 网页,在响应内容中编写HTML源码,如 HttpResponse( '<html><body>... </body></html>')
。
尽管这是一-种可行的方法, 但并不符合实际开发。因此,Django 在 django.http
模块上进行封装,从而有了 render()
、 render_ to_ response()
和 redirect()
函数。
render()
和 render_to_response()
实现的功能是一致的。render_to_response()
自 2.0 版本以来已开始被弃用,并不代表在 2.0 版本无法使用,只是大部分开发者都使用 render()
。render()
的语法如下:
render(request, template_name, context=None, content_type=None, status=None, using=None)
函数 render()
的参数 request
和 template_name
是必需参数,其余的参数是可选参数。
各个参数说明如下:
request
:浏览器向服务器发送的请求对象,包含用户信息、请求内容和请求方式等。template_name
:HTML 模板文件名,用于生成 HTML 网页。context
:对 HTML 模板的变量赋值,以字典格式表示,默认情况下是一个空字典。content_type
:响应数据的数据格式,一般情况下使用默认值即可。status
:HTTP 状态码,默认为 200。using
:设置 HTML 模板转换生成 HTML 网页的模板引擎。
除了 render
函数外,还有 redirect()
函数。redirect()
函数用于实现请求重定向,重定向的链接以字符串的形式表示,链接的地址信息可以支持相对路径和绝对路径,例:
def login(request):
# 相对路径,代表首页地址
return redirect('/')
# 绝对路径,完整的地址信息
# return redirect('http://127.0.0.1:8000/')
数据可视化
视图除了接收用户请求和返回响应内容之外,还可以与模型(Model)实现数据交互(操作数据库)。视图相当于一个处理中心,负责接收用户请求,然后根据请求信息读取并处理后台数据,最后生成 HTML 网页返回给用户。
视图操作数据库实质是从 models.py
导入数据库映射对象,models.py
的数据库对象是通过 Django 内置的 ORM 框架构建数据库映射的,从而生成数据库对象。
对于 Django 的 ORM 我准备在后面单独详述,这里数据对象我们就手动模拟构建啦~~在 index.models.py
中添加如下代码:
class Product(object):
def __init__(self, id, name, type):
self.id = id
self.name = name
self.type = type
def list_product():
products = []
product1 = Product(1,'荣耀','手机')
product2 = Product(2,'畅玩','手机')
product3 = Product(3,'华为','手机')
product4 = Product(4,'平板电脑','平板&穿戴')
product5 = Product(5,'手环','平板&穿戴')
product6 = Product(6,'音箱','通用配件')
product7 = Product(7,'移动电源','通用配件')
products.append(product1)
products.append(product2)
products.append(product3)
products.append(product4)
products.append(product5)
products.append(product6)
products.append(product7)
return products
完成模拟数据的构建以后,接着将数据展现在网页上。修改模板文件 index/templates/index.html
内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>产品列表</title>
</head>
<body>
<ul id="cate_box" class="lf">
{% for type in type_list %}
<li>
<h3><a href="#">{{ type }}</a></h3>
<p>
{% for product in product_list %}
{% if product.type == type %}
<span>{{ product.name }}</span>
{% endif %}
{% endfor %}
</p>
</li>
{% endfor %}
</ul>
</body>
</html>
新添加的代码是 Django 的模板语法,主要将视图的变量传递给模板,通过模板引擎转换成 HTML 语言。上述代码使用循环和判断语句对变量进行分析处理,具体的模板语法会在后续讲解。最后在视图函数中编写代码,将模拟的数据与模板连接起来,实现数据可视化,修改 index/views.py
中 index
函数代码如下:
def index(request):
type_list = models.list_type()
product_list = models.list_product()
context = {'title': '产品列表', 'type_list': type_list, 'product_list': product_list}
return render(request, 'index.html', context=context, status=200)
访问效果如下:
在上述视图函数中,变量 context
是以字典的形式传递给 HTML 模板的。在实际开发过程中,如果传递的变量过多,使用变量 context
时就显得非常冗余,而且不利于日后的维护和更新。因此,使用 locals()
取代变量 context
,代码如下:
# index/views.py
def index(request):
type_list = models.list_type()
product_list = models.list_product()
return render(request, 'index.html', context=locals(), status=200)
locals()
的使用方法:在视图函数中所定义的变量名一定要与 HTML
模板的变量名相同才能生效,如视图函数的 type_list
与 HTML 模板的 type_list
,两者的变量名一致才能将视图函数的变量传递给 HTML 模板。
获取请求信息
我们知道视图是用于接收并处理用户的请求信息,请求信息存放在视图函数的参数 request
中。为了进一步了解参数 request
的属性,在 PyCharm 中使用 debug 模式启动项目,并在视图函数中设置断点功能,然后查看 request
对象的全部属性,如下图:
从上图中可以看到参数 request
的详细属性,这代表用户的请求信息。下面列出一些开发中常用到的属性:
属性 | 说明 | 实例 |
---|---|---|
COOKIES | 获取客户端(浏览器) Cookie 信息 | data = request.COOKIES |
FILES | 字典对象,包含所有的上载文件。该字典有三个键:filename 为上传文件的文件名; content-type 为上传文件的类型; content 为上传文件的原始内容 | file = request.FILES |
GET | 获取 GET 请求的请求参数,以字典形式存储 | 如 {'name': 'TOM'} ,request.GET. get('name') |
META | 获取客户端的请求头信息,以字典形式存储 | 获取客户端的 IP 地址:request.META.get('REMOTE_ADDR') |
POST | 获取 POST 请求的请求参数,以字典形式存储 | 如 {'name':'TOM'} ,request.POST.get('name') |
method | 获取该请求的请求方式(GET 或 POST 请求) | data=request.method |
path | 获取当前请求的URL地址 | path=request.path |
user | 获取当前请求的用户信息 | 获取用户名:name=request.user.username |
.上述属性中的 GET
、POST
和 method
是每个 Web 开发人员必须掌握的基本属性,属性 GET
和 POST
用于获取用户的请求参数,属性 method
用于获取用户的请求方式。
评论区