4.2 视图函数
视图函数(简称视图)是用来处理Web请求并返回响应对象的Python函数。返回对象可以是包含网页内容的响应,也可以是重定向响应,或者其他任何响应。视图函数“包裹”着开发加入的业务逻辑。只要能被Python解释器找到,这些函数可以保存在任何地方。按照惯例,可将视图函数统一放在应用或项目目录下面的views.py文件中。
4.2.1 视图函数
前面的章节已经介绍过视图函数了,我们用一个简单的视图函数来回顾一下相关内容。现在编写一个返回“高跟鞋之家欢迎您”的简单页面,示例代码如下:
分析:
(1)声明文件的编码为utf8,这是因为后面的代码包含了中文。
(2)引入HttpResponse包。
(3)定义一个名为hello的视图函数。每个视图函数都会接受一个HttpRequest对象作为第一个参数。
(4)视图函数返回HttpResponse对象。每个视图函数都应该返回一个HttpResponse对象。
Django默认带有一些处理HTTP错误的视图函数,例如:
- 视图函数django.views.defaults.page_not_found,在视图函数中抛出HTTP404异常时,Django会加载该函数来处理404错误(页面不存在错误)。
- 500服务器错误。如果视图函数出现异常,则Django会默认调用视图函数django.views.defaults.server_error。这个视图函数仅在DEBUG设置为True的时候启用。
- 403禁止访问错误。如果视图函数抛出了403异常,则Django会默认调用视图函数django.views.defaults.permission_denied。
- 400错误请求。这个视图函数的路径是django.views.defaults.bad_request。这个视图函数也仅在DEBUG设置为True的时候启用。
Django处理错误的默认行为是可以被覆盖的。在URLconf中添加自定义的处理器即可,示例代码如下:
4.2.2 请求和响应对象
Django通过请求和响应对象来传递系统状态。当页面被请求时,Django会创建一个包含有关请求元数据的HttpRequest对象,然后将这个对象作为第一个参数传给视图函数。
一般情况下,不要改变请求对象的属性。常用的请求对象属性如下。
- HttpRequest.method属性。该属性表示这次请求的HTTP方法(GET或POST)。
- HttpRequest.GET属性。该属性包含所有HTTP GET请求的参数,这是一个类似于字典类型的对象。
- HttpRequest.POST属性。该属性包含HTTP POST请求的数据,这也是一个类似字典类型的对象。
- HttpRequest.META属性。该属性包含所有HTTP头的字典。
- HttpRequest.COOKIES属性。该属性包含所有Cookie的字典。所有键和值都是字符串。
Django的中间件会为HttpRequest对象添加一些属性,有HttpRequest.session、HttpRequest.site、HttpRequest.user。
Django会主动创建请求对象,但是响应对象需要开发者创建。下面是一个简单例子:
>>> from django.http import HttpResponse # 引入响应类 >>> response = HttpResponse("Here's the text of the Web page.")# 生成响应对象
响应对象和字典对象是非常相似的,使用方法也非常相似。例如,想要设置响应头,可以像操作字典一样进行添加或删除操作:
>>> response = HttpResponse() # 生成响应对象 >>> response['Age'] = 120 # 修改响应头 >>> del response['Age'] # 删除刚添加的响应头
响应对象比较常用的属性如下。
- HttpResponse.content属性:返回的内容。
- HttpResponse.status_code属性:返回的HTTP状态码。
4.2.3 模板响应对象
HttpResponse对象可返回已经确定的内容。每次在返回响应之前确认返回的内容是一件非常麻烦的事,尤其是有时候需要在响应对象被视图构造后做一些修改,如改变模板或者放置一些公共的数据在上下文中。使用TenplateResponse可以解决以上问题。TemplateResponse对象会保留视图提供的模板和上下文信息。实际的渲染只有在真正需要的时候才发生,一个简单的示例如下:
在TemplateResponse实例返回给客户端之前,必须先进行渲染。在渲染过程,模板和上下文作为输入,转换为字节流返回给客户端。在3种情况下,渲染会发生:
- 调用SimpleTemplateResponse.render()时。
- response.content被显式赋值时。
- 模板响应中间件后,但在响应中间件之前。
一个TemplateResponse对象只能被渲染一次。第一次调用SimpleTemplateResponse.render( )方法会设置响应的内容,后面再调用这个方法不会改变响应内容。不过,当显式赋值response.content时,响应的内容时钟会发生更改,如下面的示例代码: