Kapan saya harus menggunakan ugettext_lazy?

141

Saya punya pertanyaan tentang penggunaan ugettext dan ugettext_lazyterjemahan. Saya belajar bahwa dalam model saya harus menggunakan ugettext_lazy, sementara dalam pandangan ugettext. Tetapi apakah ada tempat lain, di mana saya harus menggunakan ugettext_lazyjuga? Bagaimana dengan definisi formulir? Apakah ada perbedaan kinerja di antara mereka?

Sunting: Dan satu hal lagi. Terkadang, alih-alih ugettext_lazy, ugettext_noopdigunakan. Seperti yang dikatakan oleh dokumentasi, ugettext_noopstring hanya ditandai untuk terjemahan dan diterjemahkan sesegera mungkin sebelum menampilkannya kepada pengguna, tapi saya sedikit bingung di sini, bukankah itu mirip dengan apa yang ugettext_lazydilakukan? Masih sulit bagi saya untuk memutuskan, mana yang harus saya gunakan dalam model dan formulir saya.

Dzejkob
sumber

Jawaban:

196

ugettext() vs. ugettext_lazy()

Dalam definisi seperti formulir atau model, Anda harus menggunakan ugettext_lazykarena kode definisi ini hanya dieksekusi satu kali (kebanyakan pada startup django); ugettext_lazymenerjemahkan string dengan gaya malas, yang artinya, mis. setiap kali Anda mengakses nama atribut pada model, string tersebut akan diterjemahkan baru - yang benar-benar masuk akal karena Anda mungkin melihat model ini dalam bahasa yang berbeda sejak Django dimulai!

Dalam pandangan dan panggilan fungsi serupa, Anda dapat menggunakan ugettexttanpa masalah, karena setiap kali tampilan dipanggil ugettextakan dieksekusi, sehingga Anda akan selalu mendapatkan terjemahan yang tepat sesuai permintaan!

Mengenai ugettext_noop()

Seperti yang ditunjukkan oleh Bryce dalam jawabannya, fungsi ini menandai sebuah string yang dapat diekstraksi untuk terjemahan tetapi mengembalikan string yang tidak diterjemahkan. Ini berguna untuk menggunakan string di dua tempat - diterjemahkan dan tidak diterjemahkan. Lihat contoh berikut:

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
sumber
15
Itu lebih dimengerti daripada penjelasan di dokumentasi Django menurut saya. Terima kasih @Bernhard.
Utku
14
Terima kasih! Akan sangat membantu untuk menjelaskan kapan tidak menggunakan ugettext_lazy, seperti ketika meneruskannya ke hal-hal yang mengharapkan string seperti "" .replace, string concatenation, dan lainnya; objek proxy yang malas tidak akan berfungsi dalam kasus tersebut. Kalau tidak, jawaban ini menyiratkan bahwa Anda aman selalu menggunakan ugettext_lazy.
mrooney
4
@moneyangi kasus-kasus itu menjadi kurang penting karena mereka akan memberi Anda kesalahan jika Anda melakukannya, alih-alih diam-diam mengembalikan terjemahan bahasa yang salah. Juga, Anda dapat menggunakan "". Ganti dengan ugettext_lazy, Anda hanya perlu memanggil str () pada hasil misal lazytext = ugettext_lazy ('hello') dan kemudian menggunakan str (lazytext) .replace.
fabspro
1
bagaimana dengan msg = "An error has occurred"; logging.error(msg);return HttpResponse(_(msg))? why need _noop ?jika tanpa _noop, Django tidak akan menemukan string butuh terjemahan?
WeizhongTu
1
Terjemahan bekerja pada variabel. Sekali lagi, ini adalah contoh dokumen yang identik , jadi mengapa _noop?
WeizhongTu
17

Penggunaan _noop yang sangat baik adalah ketika Anda ingin mencatat pesan dalam bahasa Inggris untuk pengembang, tetapi menyajikan string yang diterjemahkan kepada pemirsa. Contohnya ada di http://blog.bessas.me/posts/using-gettext-in-django/

Bryce
sumber
4
Tautannya
5

Versi lazy mengembalikan objek proxy bukan string dan dalam beberapa situasi itu tidak akan berfungsi seperti yang diharapkan. Sebagai contoh:

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')

akan gagal karena baris terakhir yang akan mencoba cerita bersambung lst objek ke JSON dan bukannya string untuk "klien" itu akan memiliki objek proxy. Objek proxy tidak bisa serial ke json.

Alex Protyagov
sumber
2
Anda harus menggunakan ugettext dalam kasus ini.
sudip