Klassbaserade åsikter¶
En view är en callable som tar emot en request och returnerar ett svar. Detta kan vara mer än bara en funktion, och Django ger ett exempel på några klasser som kan användas som vyer. Dessa gör att du kan strukturera dina vyer och återanvända kod genom att utnyttja arv och mixins. Det finns också några generiska vyer för uppgifter som vi kommer till senare, men du kanske vill utforma din egen struktur av återanvändbara vyer som passar ditt användningsfall. För fullständiga detaljer, se :doc:``class-based views reference documentation</ref/class-based-views/index>`.
Grundläggande exempel¶
Django tillhandahåller basvyklasser som passar ett brett spektrum av applikationer. Alla vyer ärver från View
-klassen, som hanterar länkning av vyn till webbadresserna, HTTP-metodutskick och andra vanliga funktioner. RedirectView
tillhandahåller en HTTP-omdirigering, och TemplateView
utökar basklassen så att den också kan rendera en mall.
Användning i din URLconf¶
Det mest direkta sättet att använda generiska vyer är att skapa dem direkt i din URLconf. Om du bara ändrar några få attribut på en klassbaserad vy kan du skicka dem till as_view()
metodanropet själv:
from django.urls import path
from django.views.generic import TemplateView
urlpatterns = [
path("about/", TemplateView.as_view(template_name="about.html")),
]
Eventuella argument som skickas till as_view()
kommer att åsidosätta attribut som ställts in på klassen. I det här exemplet ställer vi in template_name
på TemplateView
. Ett liknande åsidosättningsmönster kan användas för attributet url
på RedirectView
.
Underklassificering av generiska vyer¶
Det andra, mer kraftfulla sättet att använda generiska vyer är att ärva från en befintlig vy och åsidosätta attribut (t.ex. template_name
) eller metoder (t.ex. get_context_data
) i din underklass för att tillhandahålla nya värden eller metoder. Tänk till exempel på en vy som bara visar en mall, about.html
. Django har en generisk vy för att göra detta - TemplateView
- så vi kan subklassa den och åsidosätta mallnamnet:
# some_app/views.py
from django.views.generic import TemplateView
class AboutView(TemplateView):
template_name = "about.html"
Sedan måste vi lägga till den här nya vyn i vår URLconf. TemplateView
är en klass, inte en funktion, så vi pekar URL:en till klassmetoden as_view()
istället, som ger en funktionsliknande ingång till klassbaserade vyer:
# urls.py
from django.urls import path
from some_app.views import AboutView
urlpatterns = [
path("about/", AboutView.as_view()),
]
Mer information om hur du använder de inbyggda generiska vyerna finns i nästa ämne i generiska klassbaserade vyer.
Stöd för andra HTTP-metoder¶
Anta att någon vill komma åt vårt bokbibliotek via HTTP med hjälp av vyerna som ett API. API-klienten skulle ansluta då och då och ladda ner bokdata för de böcker som publicerats sedan förra besöket. Men om inga nya böcker har dykt upp sedan dess är det slöseri med CPU-tid och bandbredd att hämta böckerna från databasen, rendera ett fullständigt svar och skicka det till klienten. Det kan vara att föredra att fråga API:et när den senaste boken publicerades.
Vi mappar URL:en till boklistans vy i URLconf:
from django.urls import path
from books.views import BookListView
urlpatterns = [
path("books/", BookListView.as_view()),
]
Och utsikten:
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
Om vyn nås från en GET
-begäran returneras en objektlista i svaret (med hjälp av mallen book_list.html
). Men om klienten skickar en HEAD
-begäran har svaret en tom body och Last-Modified
-headern anger när den senaste boken publicerades. Baserat på denna information kan klienten ladda ner hela objektlistan eller inte.
Asynkrona klassbaserade visningar¶
Förutom de synkrona (def
) metodhanterare som redan visats, kan View
subklasser definiera asynkrona (async def
) metodhanterare för att utnyttja asynkron kod med hjälp av 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!")
Inom en och samma view-klass måste alla användardefinierade metodhanterare vara antingen synkrona, med def
, eller asynkrona, med async def
. Ett ImproperlyConfigured
undantag kommer att uppstå i as_view()
om def
och async def
deklarationer blandas.
Django kommer automatiskt att upptäcka asynkrona vyer och köra dem i ett asynkront sammanhang. Du kan läsa mer om Djangos asynkrona stöd, och hur du bäst använder asynkrona vyer, i Asynkront stöd.