Django
Generiska vyer
Sök…
Introduktion
Generiska vyer är vyer som utför en viss fördefinierad åtgärd, som att skapa, redigera eller ta bort objekt eller helt enkelt visa en mall.
Generiska vyer måste skiljas från funktionella vyer, som alltid är handskrivna för att utföra de uppgifter som krävs. I ett nötskal kan man säga att generiska vyer måste konfigureras, medan funktionella vyer måste programmeras.
Generiska vyer kan spara mycket tid, särskilt när du har många standardiserade uppgifter att utföra.
Anmärkningar
Dessa exempel visar att generiska vyer generellt gör standardiserade uppgifter mycket enklare. I stället för att programmera allt från grunden konfigurerar du vad andra redan har programmerat för dig. Detta är vettigt i många situationer, eftersom det gör att du kan koncentrera dig mer på utformningen av dina projekt snarare än processerna i bakgrunden.
Ska du alltid använda dem? Nej. De är bara meningsfulla så länge dina uppgifter är ganska standardiserade (laddar, redigerar, tar bort objekt) och desto mer upprepade är dina uppgifter. Att använda en specifik generisk vy bara en gång och sedan åsidosätta alla dess metoder för att utföra mycket speficiska uppgifter kanske inte är vettigt. Du kanske är bättre med en funktionell vy här.
Men om du har gott om vyer som kräver denna funktionalitet eller om dina uppgifter stämmer överens med de definierade uppgifterna i en specifik generisk vy, är generiska vyer exakt vad du behöver för att göra ditt liv enklare.
Minsta exempel: Funktionella jämfört med generiska vyer
Exempel för en funktionsvy för att skapa ett objekt. Exklusive kommentarer och tomma rader behöver vi 15 rader kod:
# imports
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from .models import SampleObject
from .forms import SampleObjectForm
# view functioon
def create_object(request):
# when request method is 'GET', show the template
if request.method == GET:
# perform actions, such as loading a model form
form = SampleObjectForm()
return render_to_response('template.html', locals())
# if request method is 'POST', create the object and redirect
if request.method == POST:
form = SampleObjectForm(request.POST)
# save object and redirect to success page if form is valid
if form.is_valid:
form.save()
return HttpResponseRedirect('url_to_redirect_to')
# load template with form and show errors
else:
return render_to_response('template.html', locals())
Exempel för en "klassbaserad generisk vy" för att utföra samma uppgift. Vi behöver bara sju rader med kod för att uppnå samma uppgift:
from django.views.generic import CreateView
from .models import SampleObject
from .forms import SampleObjectForm
class CreateObject(CreateView):
model = SampleObject
form_class = SampleObjectForm
success_url = 'url_to_redirect_to'
Anpassa generiska vyer
Exemplet ovan fungerar bara om dina uppgifter är helt standarduppgifter. Du lägger till exempel inte extra sammanhang här.
Låt oss göra ett mer realistiskt exempel. Antag att vi vill lägga till en sidtitel i mallen. I den funktionella vyn skulle detta fungera så här - med bara en extra rad:
def create_object(request):
page_title = 'My Page Title'
# ...
return render_to_response('template.html', locals())
Detta är svårare (eller: motintutivt) att uppnå med generiska åsikter. Eftersom de är klassbaserade måste du åsidosätta en eller flera av klassens metod för att uppnå önskat resultat. I vårt exempel måste vi åsidosätta klassens metod get_context_data så:
class CreateObject(CreateView):
model = SampleObject
form_class = SampleObjectForm
success_url = 'url_to_redirect_to'
def get_context_data(self, **kwargs):
# Call class's get_context_data method to retrieve context
context = super().get_context_data(**kwargs)
context['page_title'] = 'My page title'
return context
Här behöver vi fyra ytterligare rader för att koda i stället för bara en - åtminstone för den första ytterligare kontextvariabeln som vi vill lägga till.
Generiska vyer med mixins
Den verkliga kraften i generiska vyer utvecklas när du kombinerar dem med Mixins. En mixin är bara en annan klass definierad av dig vars metoder kan ärvas av din bildklass.
Antag att du vill att varje vy ska visa den ytterligare variabeln "page_title" i mallen. Istället för att åsidosätta metoden get_context_data varje gång du definierar vyn, skapar du en mixin med den här metoden och låter dina vyer ärva från denna mixin. Låter mer komplicerat än det faktiskt är:
# Your Mixin
class CustomMixin(object):
def get_context_data(self, **kwargs):
# Call class's get_context_data method to retrieve context
context = super().get_context_data(**kwargs)
context['page_title'] = 'My page title'
return context
# Your view function now inherits from the Mixin
class CreateObject(CustomMixin, CreateView):
model = SampleObject
form_class = SampleObjectForm
success_url = 'url_to_redirect_to'
# As all other view functions which need these methods
class EditObject(CustomMixin, EditView):
model = SampleObject
# ...
Det fina med detta är att din kod blir mycket mer strukturerad än det mestadels är fallet med funktionella vyer. Hela logiken bakom specifika uppgifter ligger bara på ett ställe och en plats. Du sparar också enorma mängder tid, särskilt när du har många vyer som alltid utför samma uppgifter, utom med olika objekt