Szenario Übersicht
Bei der Entwicklung mit Django kommt es häufig vor, dass gettext_lazy
genutzt wird, um mehrsprachige Unterstützung zu gewährleisten.
Allerdings kann es vorkommen, dass gettext_lazy
plötzlich beim Erstellen von JSON-Antworten Fehler verursacht.
In diesem Artikel wird ausführlich erklärt, wieso gettext_lazy
Probleme bei der JSON-Serialisierung verursacht und wie man sie lösen kann.
Funktioniert normal vs. Fehler aufgetreten: Szenario Vergleich
Fall | Wenn es normal funktioniert | Wenn ein Fehler aufgetreten ist |
---|---|---|
LANGUAGE_MAP.get(...) Rückgabeposition |
Wert des Dictionaries | Schlüssel des Dictionaries |
Serialisierbarkeit | Ja (kein Problem) | Nein (__proxy__ Schlüssel ist nicht in JSON umwandelbar) |
Kern des Problems: Warum gibt es diesen Unterschied?
Das Objekt, das gettext_lazy
zurückgibt, ist vom Typ __proxy__
. Dieses Objekt sieht aus wie ein String, ist aber tatsächlich kein echter String.
Djangos JsonResponse
oder Pythons json.dumps()
folgt diesen Regeln:
# ✅ Möglich: Lazy-Objekte können als Wert verwendet werden (automatische str-Umwandlung)
json.dumps({'language': _('English')})
# ❌ Fehlgeschlagen: Lazy-Objekte können nicht als Schlüssel verwendet werden
json.dumps({_('English'): 'language'})
Das bedeutet, dass um als Schlüssel im Dictionary verwendet zu werden, es unbedingt ein echter String sein muss.
Das __proxy__
Objekt wird beim Gebrauch als Schlüssel nicht automatisch umgewandelt, was zu einem Fehler führt.
Warum gibt es mit dem Wert kein Problem, aber mit dem Schlüssel?
Das gettext_lazy
Objekt verursacht beim Einsatz als Wert des Dictionaries keine Schwierigkeiten, weil Django oder Python bei der JSON-Serialisierung den Wert automatisch in einen String umwandelt.
Als Schlüssel muss jedoch die JSON-Norm besagen, dass der Schlüssel unbedingt ein String sein muss. In diesem Fall wird das gettext_lazy
Objekt nicht automatisch umgewandelt und verursacht einen Serialisierungsfehler.
Fazit:
- Bei der Verwendung als Wert erfolgt intern eine str-Umwandlung, was problemlos funktioniert.
- Bei der Verwendung als Schlüssel findet die Umwandlung nicht automatisch statt, sodass ein Fehler auftritt.
Lösungsmöglichkeiten
Methode 1: Wechsel zu gettext
(Nicht lazy)
Das ist der sicherste Ansatz. Verwenden Sie den sofort in einen String umgewandelten Wert, ohne lazy.
from django.utils.translation import gettext as _ # nicht lazy!
LANGUAGE_MAP = {
"en": _("English"),
"ko": _("Koreanisch"),
"ja": _("Japanisch"),
}
- Vorteil: Keine zusätzlichen Bearbeitungen erforderlich
- Nachteil: Da die Übersetzung beim ersten Importzeitpunkt festgelegt wird, kann dies nicht mit einigen dynamischen Übersetzungsanforderungen übereinstimmen.
Methode 2: Zwangsweise str() kurz vor der JSON-Serialisierung anwenden
Wenn Sie weiterhin das lazy-Objekt verwenden möchten, wandeln Sie den Schlüssel vor dem Hinzufügen zu JSON mit str()
um.
lang = str(LANGUAGE_MAP.get(lang_code, lang_code.upper()))
- Vorteil: Bestehender Code muss kaum geändert werden
- Nachteil: Man muss ständig an die str-Umwandlung denken.
Zusatz: Übersetzungsbearbeitung auf der Client-Seite
Es gibt auch die Möglichkeit, ganz auf mehrsprachige Verarbeitung auf dem Server zu verzichten und diese im Frontend zu bearbeiten.
- Der Server sendet nur den Sprachcode
- Client-JavaScript verwaltet die Übersetzungstabelle.
Diese Methode kann je nach Projekt gewählt werden.
Zusammenfassend
gettext_lazy
sollte niemals als Dictionary-Schlüssel verwendet werden.- Vor der JSON-Serialisierung sollten Sie unbedingt in einen String umwandeln.
- Die sicherste Methode ist die sofortige Umwandlung in einen String mit
gettext
. - Wenn der bestehende Code beibehalten werden muss, vergessen Sie nicht
str(...)
zu verwenden.
Jesses Kommentar
Dieses Problem tritt an der sehr feinen Grenze zwischen mehrsprachiger Verarbeitung in Django und der Behandlung von JSON-Antworten auf.
Denken Sie in Zukunft nicht: "Früher hat es funktioniert, warum jetzt nicht?", sondern betrachten Sie es als: "Früher hatten Sie Glück" und überprüfen Sie Ihren Code.
Der Moment, in dem die Fähigkeiten eines Entwicklers wachsen, ist genau dann, wenn man solche 'Feinheiten' versteht. Wenn Sie dieses Prinzip verstehen, können Sie sowohl die mehrsprachige Verarbeitung in Django als auch die JSON-Antworten viel robuster gestalten!
Add a New Comment