基于类的视图

视图是一个可调用的,它接受请求并返回响应。这不仅仅是一个函数,Django提供了一些可用作视图的类的示例。这些使您能够通过利用继承和混合来结构化视图并重用代码。还有一些我们稍后将讨论的任务的通用视图,但您可能想要设计适合您的用例的可重用视图结构。有关完整详细信息,请参阅 class-based views reference documentation

基本实例

Django提供了适合广泛应用程序的基础视图类。所有视图继承自 View 类,该类处理将视图链接到URL、HTTP方法调度和其他常见功能。 RedirectView 提供一个HTTP重定向,并且 TemplateView 扩展基本类以使其也呈现模板。

URLinf中的使用

使用通用视图的最直接方法是直接在URLinf中创建它们。如果您仅更改基于类的视图上的一些属性,则可以将它们传递到 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() 将重写类上设置的属性。在这个例子中,我们设置 template_nameTemplateView . 类似的重写模式可用于 url 属性对 RedirectView .

子类化通用视图

使用通用视图的第二种更强大的方法是继承现有视图并重写属性(例如 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"

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

# 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通过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.
            headers={
                "Last-Modified": last_book.publication_date.strftime(
                    "%a, %d %b %Y %H:%M:%S GMT"
                )
            },
        )
        return response

如果从 GET 请求时,响应中返回对象列表(使用 book_list.html 模板)。但如果客户发出 HEAD 请求时,响应的主体是空的, Last-Modified 标题指示最近一本书的出版时间。 根据此信息,客户端可能会或不会下载完整的对象列表。

基于类的异步视图

以及同步的 (def )方法处理程序已示出, View 子类可以定义异步 (async def )方法处理程序利用异步代码 await **

import asyncio
from django.http import HttpResponse
from django.views import View


class AsyncView(View):
    async def get(self, request, *args, **kwargs):
        # Perform io-blocking view logic using await, sleep for example.
        await asyncio.sleep(1)
        return HttpResponse("Hello async world!")

在单个视图类中,所有用户定义的方法处理程序必须是同步的,使用 def ,或者都是异步的,使用 async def 。一个 ImproperlyConfigured 异常将在 as_view() 如果 defasync def 声明好坏参半。

Django将自动检测异步视图并在异步上下文中运行它们。有关Django的异步支持以及如何最好地使用异步视图的更多信息,请参阅 异步支持