Django项目开发实战
上QQ阅读APP看书,第一时间看更新

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时,响应的内容时钟会发生更改,如下面的示例代码: