基于类的视图

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

基本示例

Django提供了基本视图类,它将适用于广泛的应用程序。 所有视图都继承自View类,它处理将视图链接到URL,HTTP方法调度和其他简单功能。 RedirectView is for a simple HTTP redirect, and TemplateView extends the base class to make it also render a template.

在你的URLconf 中使用简单

使用通用视图最简单的方法是直接在你的URLconf中创建它们。 If you’re only changing a few simple attributes on a class-based view, you can simply pass them into the as_view() method call itself:

from django.urls import path
from django.views.generic import TemplateView

urlpatterns = [
    path('about/', TemplateView.as_view(template_name="about.html")),
]

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

通用视图的子类

使用泛型视图的第二种更强大的方法是继承现有视图并覆盖子类中的属性(如template_name)或方法(如get_context_data)提供新的价值或方法。 Consider, for example, a view that just displays one template, about.html. Django有一个通用的视图来执行此操作 - TemplateView - 因此我们可以对它进行子类化,并覆盖模板名称:

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

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

那么我们只需要把这个新的视图添加到我们的URLconf中。 TemplateView is a class, not a function, so we point the URL to the as_view() class method instead, which provides a function-like entry to class-based views:

# urls.py
from django.urls import path
from some_app.views import AboutView

urlpatterns = [
    path('about/', AboutView.as_view()),
]

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

支持其他HTTP方法

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

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

from django.urls import path
from books.views import BookListView

urlpatterns = [
    path('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模板返回普通和简单的对象列表。 But if the client issues a HEAD request, the response has an empty body and the Last-Modified header indicates when the most recent book was published. 根据这些信息,客户可能会或可能不会下载完整的对象列表。