Django
Generieke weergaven
Zoeken…
Invoering
Algemene weergaven zijn weergaven die een bepaalde vooraf gedefinieerde actie uitvoeren, zoals het maken, bewerken of verwijderen van objecten of het eenvoudigweg weergeven van een sjabloon.
Algemene weergaven moeten worden onderscheiden van functionele weergaven, die altijd met de hand worden geschreven om de vereiste taken uit te voeren. Kort gezegd kan worden gezegd dat generieke weergaven moeten worden geconfigureerd, terwijl functionele weergaven moeten worden geprogrammeerd.
Algemene weergaven kunnen veel tijd besparen, vooral als u veel gestandaardiseerde taken moet uitvoeren.
Opmerkingen
Deze voorbeelden laten zien dat generieke weergaven over het algemeen gestandaardiseerde taken veel eenvoudiger maken. In plaats van alles helemaal opnieuw te programmeren, configureert u wat andere mensen al voor u hebben geprogrammeerd. Dit is logisch in veel situaties, omdat u zich hierdoor meer kunt concentreren op het ontwerp van uw projecten dan op de processen op de achtergrond.
Dus, moet je ze altijd gebruiken? Nee. Ze hebben alleen zin zolang uw taken redelijk gestandaardiseerd zijn (laden, bewerken, objecten verwijderen) en hoe repetitiever uw taken zijn. Het is misschien niet logisch om één specifieke generieke weergave slechts eenmaal te gebruiken en vervolgens alle methoden te overschrijven om zeer specifieke taken uit te voeren. Misschien bent u beter af met een functionele weergave hier.
Als u echter voldoende weergaven hebt die deze functionaliteit vereisen of als uw taken uitstekend overeenkomen met de gedefinieerde taken van een specifieke generieke weergave, dan zijn generieke weergaven precies wat u nodig hebt om uw leven eenvoudiger te maken.
Minimaal voorbeeld: functionele versus generieke weergaven
Voorbeeld voor een functionele weergave om een object te maken. Exclusief opmerkingen en lege regels hebben we 15 regels code nodig:
# 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())
Voorbeeld voor een 'Class-Based Generic View' om dezelfde taak uit te voeren. We hebben slechts 7 coderegels nodig om dezelfde taak te bereiken:
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'
Generieke weergaven aanpassen
Het bovenstaande voorbeeld werkt alleen als uw taken volledig standaardtaken zijn. U voegt hier bijvoorbeeld geen extra context toe.
Laten we een realistischer voorbeeld maken. Stel dat we een paginatitel aan de sjabloon willen toevoegen. In de functionele weergave zou dit zo werken - met slechts één extra regel:
def create_object(request):
page_title = 'My Page Title'
# ...
return render_to_response('template.html', locals())
Dit is moeilijker (of: contra-intutief) te bereiken met generieke weergaven. Omdat ze op klassen zijn gebaseerd, moet u een of meerdere methoden van de klas overschrijven om het gewenste resultaat te bereiken. In ons voorbeeld moeten we de methode get_context_data van de klasse als volgt overschrijven:
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
Hier hebben we vier extra regels nodig om te coderen in plaats van slechts één - tenminste voor de eerste aanvullende contextvariabele die we willen toevoegen.
Generieke weergaven met mixins
De echte kracht van generieke weergaven ontvouwt zich wanneer u ze combineert met Mixins. Een mixin is gewoon een door u gedefinieerde klasse wiens methoden kunnen worden overgenomen door uw viewklasse.
Stel dat u in elke weergave de extra variabele 'page_title' in de sjabloon wilt weergeven. In plaats van de methode get_context_data te overschrijven telkens wanneer u de weergave definieert, maakt u een mixin met deze methode en laat u uw weergaven erven van deze mixin. Klinkt ingewikkelder dan het eigenlijk is:
# 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
# ...
Het mooie hiervan is dat uw code veel gestructureerder wordt dan meestal bij functionele weergaven. Je hele logica achter specifieke taken bevindt zich op één plaats en slechts op één plaats. U bespaart ook enorm veel tijd, vooral als u veel weergaven hebt die altijd dezelfde taken uitvoeren, behalve met verschillende objecten