Wann sollte ich ugettext_lazy verwenden?

141

Ich habe eine Frage zur Verwendung von ugettext und ugettext_lazyfür Übersetzungen. Ich habe gelernt, dass ich in Modellen verwenden sollte ugettext_lazy, während in Ansichten ugettext. Aber gibt es noch andere Orte, an denen ich auch arbeiten sollte ugettext_lazy? Was ist mit Formulardefinitionen? Gibt es Leistungsunterschiede zwischen ihnen?

Edit: Und noch etwas. Manchmal statt ugettext_lazy, ugettext_noopverwendet wird. Wie in der Dokumentation angegeben, werden ugettext_noopZeichenfolgen nur zur Übersetzung markiert und zum spätestmöglichen Zeitpunkt übersetzt, bevor sie dem Benutzer angezeigt werden. Ich bin hier jedoch wenig verwirrt. Ist das nicht ähnlich wie bei der Ausführung ugettext_lazy? Es fällt mir immer noch schwer zu entscheiden, welche ich in meinen Modellen und Formularen verwenden soll.

Dzejkob
quelle

Antworten:

196

ugettext() vs. ugettext_lazy()

In Definitionen wie Formularen oder Modellen sollten Sie verwenden, ugettext_lazyda der Code dieser Definitionen nur einmal ausgeführt wird (meistens beim Start von django). ugettext_lazyübersetzt die Saiten faul, was bedeutet, z. Jedes Mal, wenn Sie auf den Namen eines Attributs in einem Modell zugreifen, wird die Zeichenfolge neu übersetzt. Dies ist absolut sinnvoll, da Sie dieses Modell möglicherweise seit dem Start von django in verschiedenen Sprachen betrachten!

In Ansichten und ähnlichen Funktionsaufrufen können Sie diese ugettextproblemlos verwenden, da die Ansicht jedes Mal aufgerufen wirdugettext wird, sie neu ausgeführt wird, sodass Sie immer die richtige Übersetzung für die Anforderung erhalten!

Hinsichtlich ugettext_noop()

Wie Bryce in seiner Antwort hervorhob, markiert diese Funktion eine Zeichenfolge als für die Übersetzung extrahierbar, gibt jedoch die nicht übersetzte Zeichenfolge zurück. Dies ist nützlich, um die Zeichenfolge an zwei Stellen zu verwenden - übersetzt und nicht übersetzt. Siehe folgendes Beispiel:

import logging
from django.http import HttpResponse
from django.utils.translation import ugettext as _, ugettext_noop as _noop

def view(request):
    msg = _noop("An error has occurred")
    logging.error(msg)
    return HttpResponse(_(msg))
Bernhard Vallant
quelle
15
Das ist meiner Meinung nach verständlicher als die Erklärung in Djangos Dokumentation. Danke @Bernhard.
Utku
14
Vielen Dank! Es wäre auch hilfreich zu erklären, wann ugettext_lazy nicht verwendet werden soll, z. B. wenn es an Dinge übergeben wird, die eine Zeichenfolge erwarten, wie "" .replace, Zeichenfolgenverkettung und andere; Ein Lazy-Proxy-Objekt funktioniert in diesen Fällen nicht. Andernfalls impliziert diese Antwort, dass Sie sicher sind, nur immer ugettext_lazy zu verwenden.
Mrooney
4
@mrooney diese Fälle sind weniger wichtig, weil sie Ihnen einen Fehler geben, wenn Sie sie tun, anstatt stillschweigend die falsche Sprachübersetzung zurückzugeben. Sie können auch "" .replace mit ugettext_lazy verwenden. Sie müssen nur str () für das Ergebnis aufrufen, z. B. lazytext = ugettext_lazy ('hallo'), und später str (lazytext) .replace verwenden.
Fabspro
1
Was ist mit msg = "An error has occurred"; logging.error(msg);return HttpResponse(_(msg))? why need _noop, ?wenn django ohne _noopden String keine Übersetzung findet?
WeizhongTu
1
Die Übersetzung funktioniert mit Variablen. Wieder ist hier ein identisches Beispiel docs , also warum _noop?
WeizhongTu
17

Eine hervorragende Verwendung von _noop ist, wenn Sie eine Nachricht auf Englisch für die Entwickler protokollieren möchten, die übersetzte Zeichenfolge jedoch einem Betrachter präsentieren möchten. Ein Beispiel hierfür finden Sie unter http://blog.bessas.me/posts/using-gettext-in-django/

Bryce
quelle
4
Die Verbindung ist unterbrochen ...
Nalzok
5

Die Lazy-Version gibt ein Proxy-Objekt anstelle einer Zeichenfolge zurück und funktioniert in einigen Situationen nicht wie erwartet. Beispielsweise:

def get(self, request, format=None):
   search_str = request.GET.get('search', '')
   data = self.search(search_str)
   lst = []
   lst.append({'name': ugettext_lazy('Client'), 'result': data})
   return HttpResponse(json.dumps(lst), content_type='application/json')

würde fehlschlagen, da die allerletzte Zeile versuchen würde, das erste Objekt in JSON zu serialisieren, und anstelle einer Zeichenfolge für "client" ein Proxy-Objekt hätte. Das Proxy-Objekt kann nicht in json serialisiert werden.

Alex Protyagov
quelle
2
In diesen Fällen sollten Sie ugettext verwenden.
Sudip