Bali menyang blog

Kenapa Terjemahan Django Rusak (lan Cara Ndandani 10 Penyebab Paling Umum)

2026-02-04 9 menit maca
Kenapa Terjemahan Django Rusak (lan Cara Ndandani 10 Penyebab Paling Umum)

Sampeyan wis menehi tandha string kanggo terjemahan, ngasilake file .po, mbukak compilemessages, lan app sampeyan isih nuduhake basa Inggris. Sampeyan ora dhewe. Framework i18n Django kuwi kuat, nanging duwe pinggiran landhep sing bisa njebak developer sing wis pengalaman.

Panduan iki nyakup 10 alasan paling umum kenapa terjemahan Django gagal kanthi meneng, karo gejala lan solusi sing pas kanggo saben masalah.

1. Lali Mbukak compilemessages Sawise Nyunting File .po

Sampeyan nyunting file .po (manual utawa nganggo alat), nanging teks sing wis diterjemahake ora tau muncul. App terus nuduhake string asli basa Inggris.

Django ora maca file .po nalika runtime. Malah maca file biner .mo (machine object) sing wis dikompilasi. Yen sampeyan nyunting file .po tanpa ngompilasi maneh, Django ora ngerti yen ana sing owah.

Bukak compilemessages sawise saben owah-owahan file .po:

python manage.py compilemessages

Yen sampeyan ngotomatisake terjemahan nganggo TranslateBot, tambahake compilemessages minangka langkah pungkasan ing alur kerja sampeyan:

python manage.py makemessages -a --no-obsolete
python manage.py translate
python manage.py compilemessages

2. Ora Ana {% load i18n %} ing Template

Sampeyan nggunakake {% trans "Hello" %} ing template, nanging Django nggawe TemplateSyntaxError. Utawa luwih elek, tag kasebut meneng wae ora ngapa-ngapa yen mesin template salah konfigurasi.

Tag {% trans %} lan {% blocktrans %} ana ing pustaka tag template i18n Django. Tanpa dimuat, mesin template ora ngenali tag kasebut.

Tambahake {% load i18n %} ing ndhuwur saben template sing nggunakake tag terjemahan:

{% load i18n %}

<h1>{% trans "Welcome to our site" %}</h1>
<p>{% blocktrans with name=user.name %}Hello, {{ name }}!{% endblocktrans %}</p>

Iki syarat saben template. Sanajan template induk wis dimuat i18n, template anak sing nggunakake tag terjemahan tetep butuh deklarasi {% load i18n %} dhewe.

3. LocaleMiddleware Ora Ana ing MIDDLEWARE utawa Posisine Salah

Django tansah nyajikake konten ing basa standar tanpa ndeleng header Accept-Language browser, awalan URL, utawa setelan sesi.

LocaleMiddleware nemtokake basa aktif kanggo saben request. Tanpa iku, Django standar menyang LANGUAGE_CODE lan ora nggatekake kabeh mekanisme pemilihan basa. Posisine ing tumpukan middleware uga penting, amarga butuh akses menyang data sesi lan resolusi URL.

Tambahake LocaleMiddleware menyang setelan MIDDLEWARE sampeyan, sawise SessionMiddleware lan CommonMiddleware:

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.locale.LocaleMiddleware",  # Must be after SessionMiddleware
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
]

Uga pastikake django.conf.urls.i18n disertakake ing konfigurasi URL yen sampeyan nggunakake ganti basa berbasis URL:

from django.conf.urls.i18n import i18n_patterns

urlpatterns = i18n_patterns(
    path("", include("myapp.urls")),
)

4. Kode Basa Ora Cocog (contone pt-br vs pt_BR)

Terjemahan ana ing file .po sampeyan, compilemessages sukses, nanging Django ora nggatekake terjemahan kanggo locale tartamtu.

Django ngarepake direktori locale ngikuti format <language>_<COUNTRY> nganggo pemisah garis bawah lan kode negara huruf gedhe. Contone, pt_BR kanggo basa Portugis Brasil. Yen direktori sampeyan dijenengi pt-br, pt-BR, utawa ptBR, Django ora bakal nemokake. Padha uga kanggo setelan LANGUAGES: kode ing kana nggunakake tanda hubung (pt-br), nanging sistem file nggunakake garis bawah (pt_BR).

Pastikake struktur direktori sampeyan cocog karo sing diarepake Django:

locale/
    pt_BR/
        LC_MESSAGES/
            django.po
            django.mo

Lan ing setelan sampeyan, gunakake format nganggo tanda hubung:

LANGUAGES = [
    ("en", "English"),
    ("pt-br", "Brazilian Portuguese"),
    ("zh-hans", "Simplified Chinese"),
]

Nalika mbukak makemessages, gunakake format garis bawah kanggo flag locale:

python manage.py makemessages -l pt_BR

5. Entri Fuzzy Dilewati kanthi Meneng Nalika Kompilasi

Ana terjemahan ing file .po, nanging Django nuduhake string asli basa Inggris nalika runtime kanggo entri tartamtu kuwi. Iki pancen njengkelake banget amarga terjemahane ana ing file.

Nalika makemessages Django ndeteksi string sumber sing rada owah, dheweke menehi tandha terjemahan sing wis ana minangka "fuzzy" (tegese perkiraan sing butuh review manusia). Perintah compilemessages ngliwati kabeh entri fuzzy, nganggep minangka durung diterjemahake. Dadi entri katon wis diterjemahake ing file .po, nanging file .mo ora nyertakake.

Entri fuzzy katon kaya ngene:

#, fuzzy
msgid "Welcome to our website!"
msgstr "Welkom op onze website!"

Review terjemahane, nganyari msgstr yen perlu, banjur busak flag #, fuzzy:

msgid "Welcome to our website!"
msgstr "Welkom op onze website!"

Banjur kompilasi maneh:

python manage.py compilemessages

Ing proyek sing luwih gedhe, entri fuzzy numpuk lan gampang dilewati. Perintah check_translations TranslateBot nangkep iki kanthi otomatis:

python manage.py check_translations
locale/nl/LC_MESSAGES/django.po: 0 untranslated, 3 fuzzy
CommandError: Translation check failed

Tambahake check_translations --makemessages menyang pipeline CI sampeyan lan sampeyan ora bakal ngirim entri fuzzy maneh.

6. LOCALE_PATHS Ora Dikonfigurasi utawa Ngarah menyang Direktori Salah

makemessages nggawe file .po ing sawijining lokasi, nanging Django nggoleki ing panggonan liya. Terjemahan ana ing disk nanging ora tau dimuat.

Django nggoleki file terjemahan kanthi urutan tartamtu: direktori LOCALE_PATHS dhisik, banjur direktori locale/ saben app, lan pungkasane direktori locale/ proyek. Yen LOCALE_PATHS ora disetel utawa ngarah menyang path sing salah, Django bisa uga ora nemokake file .po sampeyan.

Setel LOCALE_PATHS ing setelan sampeyan menyang path absolut:

from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

LOCALE_PATHS = [
    BASE_DIR / "locale",
]

Verifikasi yen direktori ana lan ngemot struktur sing diarepake:

locale/
    de/
        LC_MESSAGES/
            django.po
            django.mo
    nl/
        LC_MESSAGES/
            django.po
            django.mo

Kesalahan umum yaiku nyetel LOCALE_PATHS menyang locale/ (relatif) tinimbang path absolut. Django ora ngrampungake path relatif saka root proyek sampeyan. Gumantung marang direktori kerja proses, sing asring ora kaya sing diarepake.

7. Cache Nyajikake Terjemahan Lawas

Sampeyan wis nganyari lan ngompilasi terjemahan, nanging teks lawas terus muncul. Mbaleni server ndandani masalah kasebut.

Katalog terjemahan Django dimuat sepisan saben proses. Ing produksi, server WSGI/ASGI kaya Gunicorn utawa Uvicorn njaga proses worker tetep urip kanggo wektu sing suwe. File .mo bisa uga wis owah ing disk, nanging proses sing mlaku isih duwe terjemahan lawas ing memori. Kajaba iku, yen sampeyan nggunakake framework cache Django utawa reverse proxy kaya Nginx utawa Cloudflare, respon sing di-cache bakal nyajikake konten lawas nganti kadaluwarsa.

Bukak ulang server aplikasi sampeyan sawise deploy terjemahan anyar:

# Gunicorn
kill -HUP $(cat /tmp/gunicorn.pid)

# Systemd
sudo systemctl restart myapp

# Docker
docker compose restart web

Kanggo framework cache Django, busak cache sawise nganyari terjemahan:

from django.core.cache import cache
cache.clear()

Ing pengembangan, runserver otomatis dimuat ulang nalika file Python owah nanging ora ngawasi file .mo. Sampeyan kudu mbaleni kanthi manual sawise mbukak compilemessages.

8. String Ora Dibungkus ing gettext (_() utawa {% trans %})

makemessages ora ngekstrak string tartamtu, dadi ora tau muncul ing file .po sampeyan lan ora tau diterjemahake. Iki masalah paling dhasar lan uga paling gampang dilewati ing codebase gedhe.

Perintah makemessages Django nggunakake xgettext kanggo mindai kode sumber sampeyan kanggo tandha terjemahan. Yen string ora dibungkus ing gettext() (biasane dialiasi minangka _()), gettext_lazy(), {% trans %}, utawa {% blocktrans %}, ora katon kanggo proses ekstraksi.

Bungkus saben string sing dideleng pangguna:

# Python code
from django.utils.translation import gettext_lazy as _

class Article(models.Model):
    class Meta:
        verbose_name = _("article")
        verbose_name_plural = _("articles")

# Views
from django.utils.translation import gettext as _

def my_view(request):
    message = _("Your changes have been saved.")
    return HttpResponse(message)
<!-- Templates -->
{% load i18n %}
<h1>{% trans "Welcome" %}</h1>
<p>{% blocktrans with count=items|length %}You have {{ count }} items.{% endblocktrans %}</p>

Gunakake flag --dry-run TranslateBot kanggo pratinjau string sing saiki durung diterjemahake, supaya sampeyan bisa nangkep string sing kelewatan nalika ekstraksi:

python manage.py translate --target-lang de --dry-run

Iki nuduhake kabeh entri sing durung diterjemahake ing file .po sampeyan tanpa nggawe panggilan API utawa owah-owahan apa wae.

9. f-string Ora Bisa Diterjemahake (Watesan Django)

Sampeyan mbungkus f-string ing _() lan entuk kesalahan sintaksis, utawa makemessages ngekstrak string rusak/sebagian sing ora bisa diterjemahake.

f-string Python dievaluasi nalika runtime. Alat ekstraksi xgettext ngurai kode sumber kanthi statis, dadi ora bisa ngevaluasi ekspresi Python ing jero kurung {}. Iki tegese _(f"Hello, {name}") diekstrak minangka string sing ngemot ekspresi literal {name} (utawa gagal diekstrak kabeh), lan entri .po sing diasilake ora bakal cocog karo string runtime.

Gunakake format % Django utawa .format() nganggo placeholder sing dijenengi:

# Wrong -- f-string cannot be extracted
message = _(f"Hello, {user.name}! You have {count} new messages.")

# Correct -- named placeholders
message = _("Hello, %(name)s! You have %(count)d new messages.") % {
    "name": user.name,
    "count": count,
}

# Also correct -- .format() with positional args
message = _("Hello, {0}! You have {1} new messages.").format(user.name, count)

Iki dudu watesan TranslateBot utawa alat. Iki fundamental kanggo cara kerja gettext. String sumber kudu dadi literal statis supaya bisa diekstrak lan digoleki nalika runtime.

TranslateBot njaga kabeh format placeholder iki (%(name)s, {0}, %s, tag HTML) nalika terjemahan, dadi string sing wis diterjemahake tetep bisa digunakake kanthi lengkap.

10. Kesalahan Format String Placeholder Ngrusak Kompilasi .po

compilemessages gagal kanthi kesalahan, utawa file .po duwe ketidakcocokan flag #, python-format, lan entri dibuang kanthi meneng.

Nalika string sumber ngemot placeholder format Python kaya %(name)s, Django menehi tandha entri .po nganggo #, python-format. Yen terjemahane duwe placeholder sing beda (salah ketik kaya %(nome)s, placeholder sing ilang, utawa sing kebanyakan) alat gettext bisa nolak entri utawa compilemessages bisa gagal. Iki biasane kedadeyan karo terjemahan manual utawa alat terjemahan AI sing ora ngerti semantik placeholder.

Entri sing rusak katon kaya ngene:

#, python-format
msgid "Hello, %(name)s! You have %(count)d new messages."
msgstr "Hallo, %(naam)s! Je hebt %(count)d nieuwe berichten."

Ing kene %(naam)s harusne %(name)s. Placeholder kudu cocog persis karo sumber.

Pastikake string sing diterjemahake ngemot placeholder sing persis padha karo sumber. Priksa salah ketik, placeholder sing ilang, lan placeholder sing kebanyakan.

Iki salah sawijining wilayah sing TranslateBot menehi keuntungan nyata. Logika pelestarian placeholder njamin yen kabeh format string (%(name)s, {0}, %s) ing output sing diterjemahake cocog persis karo sumber. Penanganan placeholder dicakup 100% test coverage, dadi kesalahan format string saka terjemahan diilangi ing tingkat alat tinimbang ditangkep nalika waktu kompilasi.

Yen sampeyan nerjemahake kanthi manual utawa nggunakake alat sing ora nangani placeholder, validasi file .po sampeyan nganggo:

msgfmt --check-format locale/de/LC_MESSAGES/django.po

Iki mbukak validasi format string gettext lan nglaporake ketidakcocokan apa wae.

Nggabungake Kabeh: Alur Kerja Defensif

Akeh saka masalah iki duwe sebab utama sing padha: langkah manual sing gampang dilalekake. Iki alur kerja sing nyegah kabeh 10 masalah:

# 1. Extract strings (catches #8 -- any new gettext-wrapped strings)
python manage.py makemessages -a --no-obsolete

# 2. Translate (catches #1, #5, #8, #9, #10 -- handles untranslated,
#    fuzzy, and placeholder issues automatically)
python manage.py translate

# 3. Compile (catches #1 -- generates .mo files)
python manage.py compilemessages

# 4. Verify in CI (catches everything that slipped through)
python manage.py check_translations --makemessages

Tambahake langkah 4 menyang pipeline CI sampeyan lan string sing durung diterjemahake, entri fuzzy, lan kesalahan format bakal nggagalake build sadurunge tekan produksi.

Tabel Referensi Cepet

Sebab Gejala Solusi Satu Baris
Ora ana compilemessages Terjemahan ana nanging ora muncul python manage.py compilemessages
Ora ana {% load i18n %} TemplateSyntaxError ing {% trans %} Tambahake {% load i18n %} menyang template
Ora ana LocaleMiddleware Basa tansah standar basa Inggris Tambahake django.middleware.locale.LocaleMiddleware menyang MIDDLEWARE
Kode basa ora cocog Direktori locale ora ditemokake Gunakake pt_BR (garis bawah) kanggo direktori, pt-br (tanda hubung) kanggo setelan
Entri fuzzy dilewati Terjemahan ing .po nanging ora ing app Busak flag #, fuzzy sawise review
LOCALE_PATHS salah File .po ana nanging Django ora nggatekake Setel LOCALE_PATHS menyang path absolut
Terjemahan sing di-cache Teks lawas muncul sawise update Bukak ulang server aplikasi
String ora ing gettext String ilang saka file .po Bungkus ing _() utawa {% trans %}
f-string ing gettext Ekstraksi rusak utawa ketidakcocokan runtime Ganti nganggo placeholder % utawa .format()
Placeholder ora cocog compilemessages gagal utawa entri dibuang Cocogake placeholder kanthi persis antara sumber lan terjemahan

Akeh saka masalah iki ilang nalika sampeyan ngotomatisake langkah terjemahan lan ngetrapake pemeriksaan ing CI. Perintah translate TranslateBot nangani pelestarian placeholder lan terjemahan bertahap, dene check_translations nangkep apa wae sing lolos (entri sing durung diterjemahake, flag fuzzy, lan masalah format string) sadurunge tekan produksi.

Mandheg nyunting file .po kanthi manual

TranslateBot ngotomatisasi terjemahan Django nganggo AI. Siji printah, kabeh basa sampeyan, murah banget saben terjemahan.