Django: het verschil tussen gettext en gettext_lazy afklaring (evaluatiepunt begrijpen)
Wanneer je Django i18n gebruikt, schommelt je vaak tussen gettext() en gettext_lazy() door. De meeste verwarring ontstaat doordat je probeert de "verschillen" als termen te onthouden.
Het kernpunt is simpel.
gettextvertaalt nu (direct evalueren, eager)gettext_lazyvertaalt later (lazy evaluatie, lazy)
Met dit ene evaluatiepunt kun je bijna alle gevallen ordenen.
Waarom bepaalt het "wanneer" vertalen belangrijk?
Django verandert meestal de taal per verzoek (request).

- Middleware kijkt naar het verzoek en activeert
activate("ko")/activate("en")om de huidige thread/context-taal te activeren. - Bij het renderen van templates, formulieren of admin-schermen moet de vertaling in die taal plaatsvinden.
Met andere woorden, het moment waarop je een string vertaalt bepaalt het resultaat.
gettext() : "nu" vertalen en een string teruggeven
from django.utils.translation import gettext as _
def view(request):
message = _("Welcome") # vertaald op het moment dat deze regel wordt uitgevoerd
return HttpResponse(message)
- Wordt aangeroepen binnen een functie/view (runtime) werkt het meestal zoals verwacht.
- Wordt echter aangeroepen op module-importtijd, kan het problemen veroorzaken.
Veelgemaakte valkuil: gettext() gebruiken in module-constanten
# app/constants.py
from django.utils.translation import gettext as _
WELCOME = _("Welcome") # ❌ kan vast blijven op de taal van de serverstart/import
In dit geval blijft WELCOME een vaste vertaalde string, zelfs als de taal later verandert (vooral in omgevingen waar import slechts één keer gebeurt).
gettext_lazy() : een proxy die later vertaald wordt
from django.utils.translation import gettext_lazy as _
WELCOME = _("Welcome") # ✅ een object dat pas vertaald wordt wanneer nodig
gettext_lazy() levert meestal een "lazy object (proxy)".
- Bij het renderen van formulieren/templates/admin wordt het vertaald.
- Het gebeurt op het moment dat de string als tekst wordt gerenderd.
Samenvatting: In plekken waar de taal bij het renderen wordt bepaald, is lazy vaak de juiste keuze.
Praktische regels: waar wat gebruiken?
1) "Maak nu een scherm/antwoord" → gettext
- In views of service-logica die direct een string maken voor een antwoord of log.
from django.utils.translation import gettext as _
def signup_done(request):
return JsonResponse({"message": _("Signup completed.")})
2) "Definitie die bij import geëvalueerd kan worden" → gettext_lazy
verbose_name,help_textvan modellenlabel,help_textvan formulierveldenlabelvan DRF serializer velden (vergelijkbare reden)- Beschrijvingen in admin
list_display(definitie vooraf, render later)
from django.db import models
from django.utils.translation import gettext_lazy as _
class Article(models.Model):
title = models.CharField(_("title"), max_length=100)
status = models.CharField(
_("status"),
max_length=20,
choices=[
("draft", _("Draft")),
("published", _("Published")),
],
help_text=_("Visibility of the article."),
)
3) "Module‑niveau constant/choices" → meestal gettext_lazy
- Herbruikbare constanten zijn het veiligst als lazy.
from django.utils.translation import gettext_lazy as _
STATUS_CHOICES = [
("draft", _("Draft")),
("published", _("Published")),
]
4) "String naar externe systemen (log, derde‑partij API, header, etc.)" → gettext of force-evaluatie van lazy
- Een lazy object rechtstreeks doorgeven kan onverwachte types/serialisatieproblemen veroorzaken.
from django.utils.translation import gettext_lazy as _
from django.utils.encoding import force_str
msg = _("Welcome")
logger.info(force_str(msg)) # ✅ converteert naar echte string
5) "String samenvoegen/formatteren" → overweeg speciale lazy‑hulpmiddelen
- Het mengen van lazy berichten met f‑strings of
str.format()kan het evaluatiepunt verwarren. Django biedtformat_lazyvoor dit doel.
from django.utils.translation import gettext_lazy as _
from django.utils.text import format_lazy
title = format_lazy("{}: {}", _("Error"), _("Invalid token"))
Of gebruik de oude %‑formattering voor eenvoudiger beheer.
from django.utils.translation import gettext as _
message = _("Hello, %(name)s!") % {"name": user.username}
De drie meest voorkomende fouten
Fout 1) gettext() gebruiken bij module‑import → vaste vertaling
- Bij constanten/choices overweeg altijd lazy.
Fout 2) Lazy object rechtstreeks in JSON/ log plaatsen
- Converteer eerst met
force_str().
Fout 3) f‑string gebruiken om een vertaalde string te bouwen
# ❌ niet aanbevolen
_("Hello") + f" {user.username}"
- De vertaalde eenheid wordt opgesplitst (taal‑specifieke woordvolgorde) en het evaluatiepunt wordt complexer.
- Gebruik variabele vervanging binnen de vertaalde string.
# ✅ aanbevolen
_("Hello, %(name)s!") % {"name": user.username}
Tips om verwarring te verminderen
De meest effectieve manier om verwarring te verminderen is om de betekenis van _ te uniformeren per bestandstype.
- In
models.py,forms.py,admin.py(definitie eerst):from django.utils.translation import gettext_lazy as _ - In
views.py,services.py(uitvoering eerst):from django.utils.translation import gettext as _
Op deze manier ontstaat een basisregel: "Hier is lazy de standaard", waardoor fouten afnemen.
Samenvatting
- Directe evaluatie veilig bij runtime‑logica:
gettext - Later gerenderd (definitie/metadata/constanten/labels):
gettext_lazy - Extern naar buiten: gebruik
force_strindien nodig - Lazy + format:
format_lazyof variabele vervanging binnen de vertaalde string
Met deze richtlijnen kun je de verwarring rond gettext en gettext_lazy minimaliseren en automatisch de juiste keuze maken.
Gerelateerde artikelen
- Problemen met het gebruik van gettext_lazy in JSON-sleutels en oplossingen
댓글이 없습니다.