基于类的视图

视图是可调用的,它接收请求并返回响应。 这可能不仅仅是一个函数,Django提供了一些可用作视图的类的示例。 这些允许您通过利用继承和mixin来构建视图并重用代码。 对于我们稍后会介绍的简单任务,还有一些通用视图,但您可能希望设计适合您的用例的可重用视图结构。 有关完整的详细信息,请参阅基于类的视图参考文档

基本示例

Django提供适合各种应用程序的基本视图类。 所有视图都继承自View类,该类处理将视图链接到URL,HTTP方法调度和其他简单功能。 RedirectView用于简单的HTTP重定向,TemplateView扩展基类以使其也呈现模板。

在URLconf中使用简单

使用通用视图的最简单方法是直接在URLconf中创建它们。 如果您只是在基于类的视图上更改一些简单属性,则只需将它们传递给as_view()方法调用本身:

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)提供新的价值观或方法。 例如,考虑一个只显示一个模板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.urls import path
from some_app.views import AboutView

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

有关如何使用内置通用视图的更多信息,请参阅基于通用类的视图的下一个主题。

支持其他HTTP方法

假设某人想要使用视图作为API来通过HTTP访问我们的图书库。 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模板)。 但是,如果客户端发出HEAD请求,则响应具有空主体,Last-Modified标头指示最近发布的书籍的时间。 根据此信息,客户端可能会也可能不会下载完整的对象列表。