基于类的视图

视图是可调用的,它接受请求并返回响应。这不仅仅是一个函数,Django提供了一些可以用作视图的类的示例。它们允许您通过利用继承和mixin构建视图和重用代码。还有一些任务的通用视图,我们将在后面讨论这些视图,但是您可能需要设计适合您的用例的可重用视图结构。有关详细信息,请参见 class-based views reference documentation .

基本实例

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() 将重写类上设置的属性。在这个例子中,我们设置 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"

然后我们需要将这个新视图添加到URLconf中。 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的异步支持以及如何最好地使用异步视图的更多信息,请参阅 异步支持