In het vorige artikel hebben we gekeken naar waarom klasse-gebaseerde weergaven (CBV) in Django nodig zijn en welke voordelen ze hebben in vergelijking met functie-gebaseerde weergaven (FBV). In deze post gaan we dieper in op de basis weergaveklasse van Django, die als fundament voor alle CBV's kan worden beschouwd.
"Om CBV goed te begrijpen, is het belangrijk om te begrijpen hoe django.views.View werkt en welke structuur het heeft."
1. Wat is een Django View klasse?
Alle klasse-gebaseerde weergaven in Django zijn gebaseerd op de django.views.View
klasse en worden als volgt geërfd:
from django.views import View
class MyView(View):
def get(self, request, *args, **kwargs):
# Logica voor het verwerken van een GET-verzoek
...
def post(self, request, *args, **kwargs):
# Logica voor het verwerken van een POST-verzoek
...
Kenmerken van de View klasse
-
Scheiding van methoden per HTTP-methode
Wanneer een verzoek binnenkomt, roept Django intern automatisch de functie aan die overeenkomt met de verzoekmethode via dedispatch()
methode, zoalsget()
,post()
,put()
,delete()
.- Het gebruik van een voorwaarde zoals "if request.method == 'GET': … else: …" zoals bij FBV is niet nodig, zodat de code structuur schoner is.
-
Overerving en uitbreidbaarheid
Door de View klasse te erven, kunnen meerdere kindweergaven worden gemaakt, waarbij gemeenschappelijke logica in de bovenliggende klasse en specifieke logica in de kindklasse worden geplaatst, wat de herbruikbaarheid van code maximaliseert.
2. Basisstructuur en principes van de View klasse
Het eenvoudigste voorbeeld
# views.py
from django.http import HttpResponse
from django.views import View
class HelloCBV(View):
def get(self, request, *args, **kwargs):
return HttpResponse("Hallo, CBV!")
-
get()
-methode: Deze wordt uitgevoerd wanneer er een GET-verzoek (bijvoorbeeld via de URL of een link) wordt verzonden vanuit de browser. -
HttpResponse("Hallo, CBV!")
: Dit maakt en retourneert een tekstvormig antwoord.
urls.py verbinden
# urls.py
from django.urls import path
from .views import HelloCBV
urlpatterns = [
path('hello/', HelloCBV.as_view(), name='hello_cbv'),
]
-
.as_view()
methode transformeert de CBV naar een formaat dat Django kan begrijpen. -
Wanneer het URL-patroon is verbonden, wordt de
get()
methode vanHelloCBV
aangeroepen wanneer er een GET-verzoek binnenkomt ophttp://example.com/hello/
.
3. Gebruik en praktische voorbeelden van de View klasse
Het is zeldzaam dat we alleen een “string teruggeven” zoals in het bovenstaande voorbeeld. Vaak in echte projecten worden JSON-antwoorden, template-rendering, of databasetaken uitgevoerd. Hier bekijken we JSON-antwoorden en template-rendering als voorbeelden.
3.1 Voorbeeld van JSON-antwoorden
# views.py
from django.http import JsonResponse
from django.views import View
class UserDataView(View):
def get(self, request, *args, **kwargs):
# Bijvoorbeeld: Stel dat we een user_id als GET-parameter ontvangen
user_id = request.GET.get('user_id', None)
if not user_id:
return JsonResponse({'error': 'Geen user_id opgegeven'}, status=400)
# In werkelijkheid voeren we een DB-query uit
user_data = {
'id': user_id,
'name': f'User_{user_id}',
'role': 'admin'
}
return JsonResponse(user_data, status=200)
def post(self, request, *args, **kwargs):
# We kunnen JSON of formgegevens parseren uit het POST-verzoeklichaam.
# request.POST, request.body, request.FILES kunnen worden gebruikt
# In een echte service kan er een logica voor JSON-parsing en DB-opslag worden toegevoegd
new_user_data = {
'id': 123,
'name': 'NewUser',
'role': 'member'
}
return JsonResponse(new_user_data, status=201)
-
JsonResponse
: Dit is een handige tool in Django om JSON-antwoorden te genereren. -
request.GET
,request.POST
: Hiermee kunnen GET-/POST-parameters uit het HttpRequest-object in Django worden gehaald. -
In de praktijk worden DB-modellen gekoppeld of serializers gebruikt om gegevens op een meer gestructureerde manier te verwerken.
3.2 Voorbeeld van template-rendering
# views.py
from django.shortcuts import render
from django.views import View
class GreetingView(View):
def get(self, request, *args, **kwargs):
context = {
'title': 'Welkom op mijn site',
'greeting': 'Hallo, dit is een GreetingView!'
}
return render(request, 'greeting.html', context)
<!-- templates/greeting.html -->
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ greeting }}</h1>
</body>
</html>
-
render()
functie zoekt het templatebestand (greeting.html
) en retourneert de gerenderde HTML als eenHttpResponse
. -
Zo kan de template-rendering eenvoudig binnen de CBV worden gedaan.
4. Uitbreiding en herbruikbaarheid van de View klasse
Een van de grootste redenen waarom de View klasse nuttig is, is “code herbruikbaarheid”. Naarmate projecten groter worden, is het veel efficiënter om gemeenschappelijke logica (bijvoorbeeld logging, autorisatie, verwerking van gemeenschappelijke gegevens) in de bovenliggende klasse te plaatsen en in de kindklassen te gebruiken.
4.1 Gemeenschappelijke logica in de bovenliggende klasse
# views.py
from django.http import JsonResponse
from django.views import View
class BaseLoggingView(View):
def dispatch(self, request, *args, **kwargs):
# Voer gemeenschappelijke logica uit voor alle verzoeken (GET/POST etc.)
print(f"[Log] {request.method} verzoek op {request.path}")
return super().dispatch(request, *args, **kwargs)
class ChildLoggingView(BaseLoggingView):
def get(self, request, *args, **kwargs):
data = {'message': 'GET antwoord van kind'}
return JsonResponse(data)
def post(self, request, *args, **kwargs):
data = {'message': 'POST antwoord van kind'}
return JsonResponse(data)
-
dispatch()
methode: Dit is de kernmethode waarmee je de uitvoering van de viewlogica vóór en na het aanroepen kunt beheersen. -
In dit voorbeeld worden logs voor alle verzoeken vastgelegd en vervolgens wordt
super().dispatch()
gebruikt om de daadwerkelijkeget()
,post()
, enz. aan te roepen.
4.2 Functie toevoeging via Mixin
In Django wordt vaak de techniek Mixin gebruikt om “specifieke functies alleen in te voegen”. Bijvoorbeeld, LoginRequiredMixin (voor het controleren van inlogstatus) en PermissionRequiredMixin (voor het controleren van rechten) worden in de CBV gebruikt.
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views import View
from django.http import JsonResponse
class SecuredView(LoginRequiredMixin, View):
def get(self, request, *args, **kwargs):
return JsonResponse({'message': 'Je bent geauthenticeerd.'})
- Mixin wordt verder behandeld in latere artikelen over generieke weergaven en machtigingsbeheer, dus het is voldoende om te weten dat functies op deze manier kunnen worden gecombineerd.
5. Eenvoudige vergelijking met FBV
Categorie | FBV (functie-gebaseerde weergave) | CBV (klasse-gebaseerde weergave) |
---|---|---|
Schrijfvorm | In functie-vorm geschreven | In klasse & methode-vorm geschreven |
HTTP-methode verwerking | if request.method == 'GET': ... else: ... |
get() , post() afzonderlijk gescheiden |
Kans op code duplicatie | Complexe logica kan leiden tot duplicerende code | Herbruikbare gemeenschappelijke logica via overerving en mixins |
Uitbreidbaarheid | Gemeenschappelijke logica zit vaak vermengd in de functie | Geschikt voor complexe vereisten via een klasse-erfstructuur |
Leesbaarheid | Voordelig voor eenvoudige prototypes | Geschikt voor een duidelijke structuur naarmate de omvang toeneemt |
-
FBV is snel te schrijven voor kleine of eenvoudige functies, terwijl CBV voordelig is voor uitbreidbaarheid en onderhoud.
-
Met name bij teamprojecten of middelgrote tot grote projecten is het efficiënt om CBV te gebruiken.
6. Dieper ingaan: dispatch()
en URL-parameters
6.1 Redenen om dispatch()
direct te overschrijven
-
Gemeenschappelijke pre- en post-processing: Hier kunnen logica zoals het controleren van databaseverbindingen of autorisatiecontroles worden uitgevoerd telkens wanneer er een verzoek binnenkomt.
-
Methode-mapping: Intern wordt
request.method.lower()
gebruikt omget()
,post()
,put()
te vinden en aan te roepen. Als je bijvoorbeeld aanvullende methoden zoalsPATCH
op een aangepaste manier wilt afhandelen, kan jedispatch()
overschrijven.
class CustomDispatchView(View):
def dispatch(self, request, *args, **kwargs):
print("Aangepaste pre-processing logica hier.")
response = super().dispatch(request, *args, **kwargs)
print("Aangepaste post-processing logica hier.")
return response
6.2 URL-parameters ontvangen
Als je in urls.py
een padparameter zoals <int:user_id>/
specificeert, kunnen de waarden in de get()
en post()
methoden van de CBV ontvangen worden via kwargs
.
# urls.py
urlpatterns = [
path('user/<int:user_id>/', UserDetailView.as_view(), name='user_detail'),
]
# views.py
class UserDetailView(View):
def get(self, request, *args, **kwargs):
user_id = kwargs.get('user_id')
# Voer een DB-query uit op user_id
return HttpResponse(f"User ID: {user_id}")
- Net als bij FBV kunnen URL-parameters uit
kwargs
worden gehaald.
7. Een rijker praktisch voorbeeld: eenvoudige forumvoorbeeld
Voor degenen die graag de View klasse iets praktischer willen gebruiken, laten we een eenvoudig voorbeeld bekijken van het maken van een lijst met berichten en een detailpagina. (In de volgende post zullen we generieke weergaven behandelen, wat het eenvoudiger maakt om CRUD te implementeren, maar hier laten we zien dat het ook mogelijk is met de basis View klasse.)
# models.py - voorbeeldmodel
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
# views.py
from django.views import View
from django.shortcuts import render, get_object_or_404
from .models import Post
# Berichtlijst
class PostListView(View):
def get(self, request, *args, **kwargs):
posts = Post.objects.order_by('-created_at')
context = {'posts': posts}
return render(request, 'post_list.html', context)
# Berichtdetail
class PostDetailView(View):
def get(self, request, *args, **kwargs):
post_id = kwargs.get('pk')
post = get_object_or_404(Post, pk=post_id)
context = {'post': post}
return render(request, 'post_detail.html', context)
<!-- post_list.html -->
<!DOCTYPE html>
<html>
<head>
<title>Berichtlijst</title>
</head>
<body>
<h1>Berichtlijst</h1>
<ul>
{% for post in posts %}
<li>
<a href="{% url 'post_detail' post.id %}">{{ post.title }}</a>
</li>
{% endfor %}
</ul>
</body>
</html>
<!-- post_detail.html -->
<!DOCTYPE html>
<html>
<head>
<title>{{ post.title }}</title>
</head>
<body>
<h1>{{ post.title }}</h1>
<p>{{ post.content }}</p>
<p>Datum van schrijven: {{ post.created_at }}</p>
</body>
</html>
# urls.py
from django.urls import path
from .views import PostListView, PostDetailView
urlpatterns = [
path('posts/', PostListView.as_view(), name='post_list'),
path('posts/<int:pk>/', PostDetailView.as_view(), name='post_detail'),
]
-
PostListView
: Bij een GET-verzoek worden alle berichten opgehaald en doorgegeven aan het template (post_list.html
). -
PostDetailView
: Een specifiek bericht wordt opgezocht op basis van de URL-parameterpk
en doorgegeven aan het template (post_detail.html
). -
Zo kun je eenvoudig lijsten en detailpagina's samenstellen met alleen de basis View klasse.
Om echter de volledige CRUD functionaliteit te realiseren, zijn Create/Update/Delete logica's nodig. De generieke weergaven (Generic Views) die Django biedt, faciliteren dit proces en dat wordt in het volgende artikel uitgebreid behandeld!
8. Conclusie en aankondiging van de volgende post
Tot zover een uitleg van hoe de basis View klasse van Django werkt en hoe deze in de praktijk kan worden toegepast. Samenvattend zijn de belangrijkste punten:
-
Door django.views.View te erven en methoden zoals
get()
/post()
/dispatch()
te overschrijven, reageer je op HTTP-verzoeken. -
Door gemeenschappelijke logica in de bovenliggende klasse te plaatsen en alleen de noodzakelijke delen in de kindweergaven te herschrijven, maximaliseer je de herbruikbaarheid van code.
-
Je kunt eenvoudig viewlogica schrijven voor verschillende scenario's zoals template-rendering, JSON-antwoorden en DB-query's.
-
Zoals het praktische voorbeeld met een eenvoudig forum laat zien, kun je met alleen de basis View klasse voldoende werkende projecten creëren.
Echter, om CRUD-taken eenvoudiger te verwerken, is het leren van de generieke weergaven (Generic Views) die Django biedt, veel gemakkelijker.
In de volgende post zullen we ons concentreren op de FormView klasse, waarmee je het proces van “gebruikersinvoer opslaan, en bij validatiefouten foutmeldingen weergeven” kunt automatiseren.
De CBV-serie gaat door!
- Deel 3: “FormView voor eenvoudige formulierverwerking”
- Deel 4: “ListView & DetailView gebruik”
- Deel 5: “CreateView, UpdateView, DeleteView voor CRUD implementatie”
- … (en verder)
Bekijk het vorige artikel
Extra referentiemateriaal
-
Django Community – Vind verschillende voorbeelden binnen de Django Community.
Ik hoop dat dit artikel een deel van je vragen over de structuur en toepassing van de basis View klasse heeft beantwoord. In de volgende post leren we hoe we het proces van “formulier invullen → valideren → foutafhandeling → redirect naar succes” eenvoudiger kunnen verwerken via de FormView, dus houd alsjeblieft de aandacht erbij!
“De View klasse van Django is niet alleen een manier om de code per HTTP-methode te scheiden, maar het is een krachtig hulpmiddel dat de uitbreidbaarheid en het onderhoud van grootschalige projecten revolutionair kan verbeteren.”
Laten we samen verder exploreren in CBV en productieve Django-ontwikkeling realiseren!
댓글이 없습니다.