Skip to main content

基于类的视图

视图是一个可调用,它接受请求并返回响应。这不仅仅是一个函数,Django提供了一些可以用作视图的类的示例。这些允许您通过利用继承和mixins来构建视图和重用代码。还有一些简单任务的通用视图,我们稍后会看到,但您可能想要设计自己的可重用视图的结构,以适合您的用例。有关详细信息,请参阅 class-based views reference documentation

基本示例

Django提供了基类视图类,它适合于广泛的应用程序。所有视图都继承自 View 类,它处理将视图链接到URL,HTTP方法调度和其他简单的功能。 RedirectView 是一个简单的HTTP重定向,TemplateView 扩展基类,使它也渲染一个模板。

在URLconf中的简单用法

使用通用视图的最简单的方法是直接在URLconf中创建它们。如果你只是改变一个基于类的视图的几个简单的属性,你可以简单地将它们传递给 as_view() 方法调用本身:

from django.conf.urls import url
from django.views.generic import TemplateView

urlpatterns = [
    url(r'^about/$', TemplateView.as_view(template_name="about.html")),
]

传递给 as_view() 的任何参数将覆盖类上设置的属性。在这个例子中,我们在 TemplateView 上设置 template_name。类似的重写模式可以用于 RedirectView 上的 url 属性。

对通用视图进行子类化

使用通用视图的第二个更强大的方法是继承现有视图,并覆盖子类中的属性(如 template_name)或方法(如 get_context_data)以提供新的值或方法。例如,考虑一个只显示一个模板 about.html 的视图。 Django有一个通用的视图来做这个 - TemplateView - 所以我们可以只是子类化它,并覆盖模板名称:

# some_app/views.py
from django.views.generic import TemplateView

class AboutView(TemplateView):
    template_name = "about.html"

然后我们只需要将这个新视图添加到我们的URLconf中。 TemplateView 是一个类,而不是一个函数,因此我们将URL指向 as_view() 类方法,它提供了一个类似函数的条目到基于类的视图:

# urls.py
from django.conf.urls import url
from some_app.views import AboutView

urlpatterns = [
    url(r'^about/$', AboutView.as_view()),
]

有关如何使用内置通用视图的更多信息,请参阅 generic class-based views 上的下一主题。

支持其他HTTP方法

假设有人想使用视图作为API访问我们的图书馆。 API客户端将立即连接,并下载自上次访问以来发布的图书的图书数据。但是如果从那时起没有出现新书,那么就浪费了CPU时间和带宽来从数据库中提取书籍,呈现完整的响应并将其发送给客户端。最好在最近一本书出版时询问API。

我们将URL映射到URLconf中的book list视图:

from django.conf.urls import url
from books.views import BookListView

urlpatterns = [
    url(r'^books/$', BookListView.as_view()),
]

和视图:

from django.http import HttpResponse
from django.views.generic import ListView
from books.models import Book

class BookListView(ListView):
    model = Book

    def head(self, *args, **kwargs):
        last_book = self.get_queryset().latest('publication_date')
        response = HttpResponse('')
        # RFC 1123 date format
        response['Last-Modified'] = last_book.publication_date.strftime('%a, %d %b %Y %H:%M:%S GMT')
        return response

如果从 GET 请求访问视图,则在响应中返回简单且简单的对象列表(使用 book_list.html 模板)。但是如果客户端发出 HEAD 请求,则响应具有空主体,并且 Last-Modified 标题指示最近的书籍何时被发布。基于该信息,客户端可以或可以不下载完整对象列表。