Dynamische webontwikkeling vereenvoudigen met Django en HTMX: De kracht van Forms en Serializers
In ons vorige artikel hebben we gekeken naar hoe HTMX gegevens naar de server verzendt.
Lees het vorige artikel: Dynamische webontwikkeling vereenvoudigen met Django en HTMX (deel 4): Payload-overdrachtsmethoden
Waar de traditionele JavaScript fetch()-methode meer gericht is op het direct creëren en verzenden van JSON-payloads, hebben we vastgesteld dat HTMX dichter bij de methode staat om waarden uit de DOM te verzamelen en als formuliergegevens te verzenden.
Dan rijst nu vanzelf de vraag:
"Wat is de meest natuurlijke manier om deze via HTMX ontvangen gegevens in Django te valideren?"
Aanvankelijk zullen velen misschien denken aan de DRF Serializer. Inderdaad, een Serializer is een krachtig validatie-instrument en kan ook zonder JSON worden gebruikt. Echter, wanneer je het met HTMX probeert te gebruiken, voelt het soms een beetje geforceerd aan.
Waarom?
De reden is simpel.
De basisfilosofie van HTMX sluit meer aan bij de wereld van HTML-formulieren, en Django heeft al een Form dat precies voor die wereld is ontworpen.
In dit artikel zullen we de verschillende manieren verkennen waarop Django Form en DRF Serializer kunnen worden gebruikt bij het verwerken van HTMX-verzoeken, en welke van de twee een natuurlijkere en praktischere keuze is.

De gegevens die HTMX verzendt, lijken uiteindelijk sterk op "formuliergegevens"
Zoals we in het vorige deel hebben gezien, verzamelt HTMX in principe waarden van HTML-elementen en stuurt deze naar de server. Dit gebeurt door invoerwaarden binnen een <form> te verzenden, specifieke elementen op te nemen met hx-include, of extra waarden toe te voegen met hx-vals.
De basisfilosofie van HTMX komt dus neer op het volgende:
- Geen directe assemblage van JavaScript-objecten
- Waarden verzamelen uit HTML-elementen
- Verzoeken naar de server sturen
- Past beter bij HTML-fragmenten als antwoord dan bij JSON
Deze werkwijze is belangrijker dan je denkt.
Want deze structuur komt vrijwel exact overeen met de typische Django Form-verwerkingsflow.
Django Form is ook ontworpen met de volgende premissen:
- De gebruiker vult een HTML-formulier in
- De server ontvangt
request.POST - Het Form valideert de gegevens
- Bij fouten wordt het opnieuw gerenderd
- Als er geen problemen zijn, worden de gegevens opgeslagen en wordt een antwoord teruggegeven
Op dit punt begint het te voelen alsof HTMX en Django Form perfect bij elkaar passen, als Assepoester en haar glazen muiltje.
Daarom lijkt het gepast om tot de volgende conclusie te komen:
Het meest natuurlijke validatie-instrument van Django dat naadloos aansluit bij HTMX is Django Form, meer nog dan DRF Serializer.
Waarom past Django Form beter?
DRF Serializer is ongetwijfeld een uitstekend hulpmiddel. Maar gezien de oorspronkelijke ontwerpprincipes is een Serializer meer gericht op gegevensserialisatie en API-invoervalidatie.
Django Form daarentegen is vanaf het begin ontworpen voor het volgende:
- Verwerking van HTML-formulierinvoer
- Validatie aan de serverzijde
- Weergave van foutmeldingen
- Behoud van ingevoerde waarden
- Herrenderen van templates
Met andere woorden, het is veel natuurlijker wanneer het wordt gekoppeld aan een methode zoals HTMX, die "een deel van de HTML opnieuw ontvangt en vervangt".
Laten we een voorbeeld bekijken.
Een gebruiker dient een reactieformulier in.
- Wat als de validatie mislukt?
- De ingevoerde inhoud moet behouden blijven
- Er moet worden getoond welk veld een probleem heeft
- Het formulier met de fouten moet gedeeltelijk opnieuw worden gerenderd
Dergelijke UX-vereisten kan Django Form uitstekend afhandelen.
Natuurlijk biedt een Serializer ook errors en is validatie mogelijk. Maar de volgende stap, namelijk "het opnieuw samenstellen van de volledige HTML-formulier UX", verloopt veel soepeler met een Form.
Dus, puur kijkend naar de compatibiliteit met HTMX, is het terecht om Form als de standaardkeuze te beschouwen.
De meest natuurlijke combinatie: HTMX + Django Form
Laten we eerst kijken naar het meest eenvoudige voorbeeld.
Een simpel formulier voor het registreren van een taak.
Definitie van het Formulier
from django import forms
class TodoForm(forms.Form):
title = forms.CharField(max_length=100, label="제목")
priority = forms.IntegerField(min_value=1, max_value=5, label="우선순위")
Nu kunnen we in de view request.POST direct in het Formulier plaatsen om het te valideren.
Verwerking in de View
from django.shortcuts import render
from django.http import HttpResponse
def todo_create(request):
if request.method == "POST":
form = TodoForm(request.POST)
if form.is_valid():
title = form.cleaned_data["title"]
priority = form.cleaned_data["priority"]
# 저장 로직 수행
# Todo.objects.create(title=title, priority=priority)
return render(request, "todos/partials/todo_item.html", {
"title": title,
"priority": priority,
})
return render(request, "todos/partials/todo_form.html", {
"form": form,
}, status=400)
form = TodoForm()
return render(request, "todos/partials/todo_form.html", {
"form": form,
})
De kernpunten hier zijn heel duidelijk:
- Ontvang de waarden die door HTMX zijn verzonden als
request.POST - Het Form valideert de gegevens
- Bij succes wordt een HTML-fragment geretourneerd
- Bij falen wordt het Formulier met daarin de fouten opnieuw gerenderd
Deze flow is zowel Django-achtig als HTMX-achtig, en bovenal eenvoudig te onderhouden.
Foutmeldingen op een natuurlijke manier opnieuw weergeven in de template
Dit is precies waar Django Form in uitblinkt.
Bij een mislukte validatie bevat het Form-object reeds de volgende informatie:
- De door de gebruiker ingevoerde waarden
- Foutmeldingen per veld
- Niet-veld gerelateerde fouten
- De status van welke velden ongeldig zijn
Daarom kan de partial-template deze informatie direct renderen.
todo_form.html
<form hx-post="{% url 'todo_create' %}" hx-target="#todo-form-wrap" hx-swap="outerHTML">
{% csrf_token %}
{% if form.non_field_errors %}
<div class="error-box">
{{ form.non_field_errors }}
</div>
{% endif %}
<div>
<label for="{{ form.title.id_for_label }}">제목</label>
{{ form.title }}
{% if form.title.errors %}
<div class="field-error">{{ form.title.errors }}</div>
{% endif %}
</div>
<div>
<label for="{{ form.priority.id_for_label }}">우선순위</label>
{{ form.priority }}
{% if form.priority.errors %}
<div class="field-error">{{ form.priority.errors }}</div>
{% endif %}
</div>
<button type="submit">등록</button>
</form>
Dit voorbeeld is zeer eenvoudig, maar toont de uitstekende synergie tussen HTMX en Django Form.
- Bij falen kan het hele formulier opnieuw worden gerenderd
- De door de gebruiker ingevoerde waarden blijven behouden
- Foutmeldingen worden op een natuurlijke manier naast de velden weergegeven
Met de traditionele fetch() + JSON + handmatige DOM-manipulatie zou je aanzienlijk veel JavaScript moeten schrijven om een dergelijke flow te implementeren. Maar met de combinatie van HTMX en Django Form kan dit veel eenvoudiger worden afgehandeld met alleen server-side code en templates.
Is een Serializer dan overbodig?
Zeggen dat een Serializer overbodig is, gaat misschien te ver. Het is beter om het zo te formuleren:
Het is niet per se nodig om een Serializer als standaardkeuze te nemen.
In de praktijk blijft een DRF Serializer onder de volgende omstandigheden nog steeds zeer aantrekkelijk:
- Als DRF al intensief wordt gebruikt in het hele project
- Als dezelfde validatielogica zowel voor API's als voor server-gerenderde schermen opnieuw moet worden gebruikt
- Als de invoervalidatielogica complex is en al goed is gestructureerd in een Serializer
- Als er plannen zijn om dezelfde functionaliteit later ook bloot te stellen aan mobiele apps of externe API's
Met andere woorden, de vraag bij een Serializer is niet zozeer "Kan ik het gebruiken met HTMX?", maar eerder:
"Levert het voordelen op voor de algehele architectuur om hier een Serializer te gebruiken?"
Een Serializer kan ook gebruikt worden
Stel bijvoorbeeld dat je al een Serializer hebt zoals hieronder:
from rest_framework import serializers
class TodoSerializer(serializers.Serializer):
title = serializers.CharField(max_length=100)
priority = serializers.IntegerField(min_value=1, max_value=5)
In dit geval kan het ook prima worden gebruikt voor HTMX-verzoeken.
from django.shortcuts import render
def todo_create_with_serializer(request):
if request.method == "POST":
serializer = TodoSerializer(data=request.POST)
if serializer.is_valid():
title = serializer.validated_data["title"]
priority = serializer.validated_data["priority"]
return render(request, "todos/partials/todo_item.html", {
"title": title,
"priority": priority,
})
return render(request, "todos/partials/todo_form_serializer.html", {
"errors": serializer.errors,
"data": request.POST,
}, status=400)
Zoals je ziet, is er technisch gezien geen enkel probleem. Een Serializer is immers geen tool die alleen JSON accepteert.
Maar hier komt een subtiel verschil naar voren.
Bij gebruik van een Form:
- Behoud van invoerwaarden
- Rendering per veld
- Foutbinding
- Connectie met de template
Dit vloeit allemaal vanzelfsprekend in elkaar over.
Bij gebruik van een Serializer daarentegen:
- Moet
serializer.errorshandmatig worden ontleed om aan de template-structuur te voldoen - Moeten bestaande invoerwaarden afzonderlijk worden doorgegeven
- Moet de ontwikkelaar meer aandacht besteden aan de koppeling met het opnieuw renderen van HTML-formulieren
Dat wil zeggen, het is bruikbaar, maar vereist iets meer handmatig werk.
Precies op dit punt kan een Serializer een beetje geforceerd aanvoelen wanneer het samen met HTMX wordt gebruikt.
Conclusie
In het vorige deel hebben we gekeken naar hoe HTMX gegevens verzendt. In dit deel hebben we samengevat wat de meest natuurlijke manier is om die gegevens in Django te valideren.
- HTMX past van nature goed bij formuliergegevens
- Django Form is precies ontworpen voor die flow
- Daarom is Form de meest natuurlijke keuze als je puur naar de compatibiliteit met HTMX kijkt
- Een DRF Serializer kan gebruikt worden, maar is eerder een strategische keuze
Persoonlijk denk ik dat om HTMX optimaal te benutten, we niet alleen "het gevoel om AJAX op een HTML-achtige manier te behandelen" moeten herontdekken, maar ook "het gevoel om Django Form en formulier-tags te gebruiken".
Gerelateerde artikelen
- Dynamische Webontwikkeling Vereenvoudigen met Django en HTMX (Deel 1)
- Dynamische webontwikkeling vereenvoudigen met Django en HTMX - Ajax (Deel 2)
- Django en HTMX: Dynamische webontwikkeling vereenvoudigen (Deel 3): Integratie met Django
- Django en HTMX: Het vereenvoudigen van dynamische webontwikkeling (deel 5)
There are no comments.