適用版本:django1.11
官網(wǎng)地址:https://docs.djangoproject.com/en/1.11/topics/class-based-views/
視圖是接收請求并返回響應(yīng)的可調(diào)用函數(shù)。 它不僅可以是函數(shù)的形式,Django還提供了一些實(shí)現(xiàn)視圖功能的類。 類視圖幫助我們通過繼承和mixin來構(gòu)建視圖以重用代碼。 django內(nèi)置一些完成簡單任務(wù)的通用視圖(稍后會介紹),但是開發(fā)人員很可能需要設(shè)計(jì)自己的可重用視圖結(jié)構(gòu)來滿足開發(fā)要求。 詳細(xì)信息請參閱基類視圖參考文檔。
- 類視圖介紹
- 內(nèi)置基類通用視圖
- 使用類視圖處理表單
- 類視圖如何使用mixins
基本例子
Django提供適用于大量應(yīng)用的基本視圖類。 所有視圖都繼承View類,View類實(shí)現(xiàn)建立視圖與URL的聯(lián)系、分配HTTP方法和其他的簡單特性。 RedirectView是一個(gè)簡單的HTTP重定向,TemplateView擴(kuò)展基類實(shí)現(xiàn)了渲染模板的功能。
在URLconf中的簡單用法
使用通用視圖最簡單的方法是直接在URLconf中創(chuàng)建它們。如果只更改類視圖的一些簡單特性,可以直接通過as_view()方法傳遞:
from django.conf.urls import url
from django.views.generic import TemplateView
urlpatterns = [
url(r'^about/$', TemplateView.as_view(template_name="about.html")),
]
任何傳入as_view()的參數(shù)都將覆蓋類的對應(yīng)屬性。在這個(gè)例子中,我們?yōu)門emplateView設(shè)置了template_name。我們可以采用類似的方法重新設(shè)置RedirectView的url屬性。
創(chuàng)建通用視圖的子類
使用通用視圖的第二個(gè)方法是繼承已存在的類視圖,并通過在子類中重寫屬性(如template_name)或方法(如get_context_data)來提供新的值或方法。比如,一個(gè)只展示一個(gè)模板(about.html)的視圖。Django內(nèi)置一個(gè)可以完成該工作的通用視圖(TemplateView),我們可以創(chuàng)建它的子類并覆蓋模板名稱:
# some_app/views.py
from django.views.generic import TemplateView
class AboutView(TemplateView):
template_name = "about.html"
然后,我們將這個(gè)新視圖添加到URLconf中就可以了。TemplateView是一個(gè)類(不是一個(gè)方法),因此我們將URL指向類的as_view()方法,該方法為類視圖提供一個(gè)函數(shù)接口:
# urls.py
from django.conf.urls import url
from some_app.views import AboutView
urlpatterns = [
url(r'^about/$', AboutView.as_view()),
]
使用內(nèi)置通用視圖的更多方法可以參考通用類視圖。
支持其他HTTP方法
假設(shè)有人想把視圖作為通過HTTP訪問我們圖書館的API。 每個(gè)人都可能隨時(shí)訪問API并下載上次訪問后發(fā)布的新書的數(shù)據(jù)。 但是如果從那以后沒有新書,那么從數(shù)據(jù)庫中獲取圖書、呈現(xiàn)完整的響應(yīng)并將其發(fā)送給客戶端則是對CPU時(shí)間和帶寬的浪費(fèi)。 更好的方法應(yīng)該是詢問API最新的書是什么時(shí)候發(fā)布的。
我們在URLconf中將圖書列表視圖映射到URL:
from django.conf.urls import url
from books.views import BookListView
urlpatterns = [
url(r'^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請求訪問該視圖,響應(yīng)將返回一個(gè)簡單的對象列表(使用book_list.html模板)。 但是如果客戶端發(fā)出HEAD請求,則響應(yīng)主體為空而Last-Modified指向最新發(fā)布的圖書的時(shí)間。 基于此信息,客戶端可能會或者不會下載完整的對象列表。