基于类的视图¶
视图是一个可调用对象,它接收请求并返回响应。它不仅仅是一个函数,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 最近发布的书籍是什么时候可能更好。
我们在 URLconf 中将 URL 映射到书籍列表视图
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()
中引发,如果混合使用了def
和async def
声明。
Django 将自动检测异步视图并在异步上下文中运行它们。您可以在异步支持 中阅读有关 Django 的异步支持以及如何最好地使用异步视图的更多信息。