Kembali ke blog

Django i18n: Panduan Lengkap Mengotomatiskan Terjemahan File .po

2026-01-28 9 menit baca
Django i18n: Panduan Lengkap Mengotomatiskan Terjemahan File .po

Jika Anda pernah merilis aplikasi Django dalam lebih dari satu bahasa, Anda pasti tahu prosesnya. Anda membungkus string Anda dalam gettext(), menjalankan makemessages, membuka file .po dengan ratusan entri, dan mulai menerjemahkan baris per baris. Untuk dua bahasa dan lima puluh string, itu masih bisa ditoleransi. Untuk enam bahasa dan lima ratus string, itu satu hari kerja penuh yang tidak akan pernah kembali.

Panduan ini membahas pipeline internasionalisasi (i18n) Django dari awal hingga akhir, menjelaskan di mana prosesnya gagal, dan menunjukkan cara mengotomatisasi bagian yang menyakitkan dengan terjemahan berbasis AI.

Alur Kerja Standar Django i18n

Sistem i18n bawaan Django dirancang dengan baik. Loop intinya terlihat seperti ini:

Langkah 1: Tandai string untuk diterjemahkan dalam kode Python dan template Anda:

from django.utils.translation import gettext as _

def dashboard(request):
    welcome = _("Welcome back, %(name)s!") % {"name": request.user.first_name}
    return render(request, "dashboard.html", {"welcome": welcome})
{% load i18n %}
<h1>{% trans "Account Settings" %}</h1>
<p>{% blocktrans %}You have {{ count }} unread messages.{% endblocktrans %}</p>

Langkah 2: Ekstrak string ke file .po:

python manage.py makemessages -l de -l fr -l nl

Ini memindai seluruh codebase Anda dan menghasilkan satu file .po per bahasa, berisi setiap string yang dapat diterjemahkan:

#: myapp/views.py:4
msgid "Welcome back, %(name)s!"
msgstr ""

#: templates/dashboard.html:2
msgid "Account Settings"
msgstr ""

Langkah 3: Terjemahkan setiap msgstr yang kosong secara manual.

Langkah 4: Kompilasi file .po yang sudah selesai menjadi file biner .mo:

python manage.py compilemessages

Langkah 1, 2, dan 4 cepat. Langkah 3 adalah di mana prosesnya berantakan.

Mengapa Terjemahan Manual Tidak Bisa Diskalakan

Aplikasi Django yang umum memiliki sekitar 200 hingga 2.000 string yang dapat diterjemahkan. Kalikan itu dengan jumlah bahasa target, dan Anda menghadapi komitmen waktu yang serius.

Ini bukan keluhan teoritis. Dalam thread Django Forum yang terkenal, seorang developer melaporkan menghabiskan 8+ jam per file .po untuk terjemahan manual. Seorang kontributor inti Django menggambarkan menghabiskan lebih dari 10 jam untuk mengintegrasikan terjemahan yang dikirim komunitas ke dalam satu rilis, sebagian besar untuk review, koreksi format, dan memperbaiki placeholder yang rusak.

Masalahnya bertambah seiring waktu:

Akar masalahnya adalah terjemahan diperlakukan sebagai peristiwa satu kali, bukan proses inkremental yang dapat diulang.

Mengotomatisasi Terjemahan dengan AI

Idenya sederhana: alih-alih manusia membuka setiap file .po dan mengisi nilai msgstr, sebuah alat membaca file, mengirim string yang belum diterjemahkan ke model AI atau API terjemahan, menulis hasilnya kembali, dan mempertahankan semua yang lain (komentar, struktur file, placeholder, bentuk jamak).

TranslateBot Django adalah paket open-source yang melakukan persis hal ini. Ia terintegrasi ke dalam sistem management command Django, sehingga cocok dengan alur kerja yang sudah Anda miliki.

Pengaturan Langkah demi Langkah

1. Instal Paket

pip install translatebot-django

Atau, jika Anda menggunakan uv (direkomendasikan):

uv add --dev translatebot-django

Menginstalnya sebagai dependensi pengembangan adalah disengaja. Anda hanya membutuhkan TranslateBot saat menghasilkan terjemahan, bukan saat runtime di produksi.

2. Tambahkan ke INSTALLED_APPS

# settings.py
INSTALLED_APPS = [
    # ...
    "translatebot_django",
]

3. Konfigurasi Provider AI Anda

# settings.py
import os

TRANSLATEBOT_API_KEY = os.getenv("OPENAI_API_KEY")
TRANSLATEBOT_MODEL = "gpt-4o-mini"

TranslateBot menggunakan LiteLLM di balik layar, yang berarti Anda dapat beralih ke model mana pun dari 100+ model dengan mengubah satu string:

Provider Nilai TRANSLATEBOT_MODEL
OpenAI gpt-4o-mini, gpt-4o
Anthropic claude-sonnet-4-5-20250929
Google gemini/gemini-2.5-flash
Azure OpenAI azure/gpt-4o-mini
DeepL Gunakan TRANSLATEBOT_PROVIDER = "deepl" sebagai gantinya

Untuk DeepL, instal ekstranya: pip install translatebot-django[deepl]. Tier gratis DeepL memberi Anda 500.000 karakter per bulan tanpa biaya, yang cukup untuk sebagian besar proyek kecil hingga menengah.

4. Tentukan Bahasa Anda

# settings.py
LANGUAGES = [
    ("en", "English"),
    ("de", "German"),
    ("fr", "French"),
    ("nl", "Dutch"),
    ("ja", "Japanese"),
]

5. Jalankan Terjemahan

python manage.py translate

Itu saja. TranslateBot memindai proyek Anda untuk file .po, mengidentifikasi entri yang belum diterjemahkan, mengirimnya ke model AI yang dikonfigurasi dalam batch yang dioptimalkan, dan menulis hasilnya kembali. Terjemahan yang sudah ada tetap tidak tersentuh.

Untuk menerjemahkan satu bahasa:

python manage.py translate --target-lang nl

Outputnya terlihat seperti ini:

Translating to Dutch (nl)...
Found 42 strings to translate
Translating batch 1/2...
Translating batch 2/2...
Successfully translated 42 strings

6. Kompilasi Seperti Biasa

python manage.py compilemessages

Alur kerja lengkap Anda sekarang adalah:

python manage.py makemessages -l de -l fr -l nl -l ja
python manage.py translate
python manage.py compilemessages

Tiga perintah. Setiap bahasa. Setiap sprint.

Inkremental secara Desain

Fitur paling penting untuk alur kerja yang dapat diulang adalah terjemahan inkremental. TranslateBot hanya menerjemahkan entri di mana msgstr kosong. Jika Anda memiliki 500 string dan 15 baru di sprint ini, hanya 15 itu yang dikirim ke API.

Ini penting karena alasan praktis:

  1. Biaya. Anda hanya membayar untuk string baru, bukan seluruh file.
  2. Kecepatan. Menerjemahkan 15 string membutuhkan detik, bukan menit.
  3. Stabilitas. Terjemahan yang sudah Anda review dan setujui tidak pernah ditimpa (kecuali Anda secara eksplisit memberikan --overwrite).

Keamanan Placeholder

Django menggunakan beberapa format placeholder: %(name)s, %s, %d, {0}, {name}, dan tag HTML inline seperti <strong> atau <a href="...">. Jika salah satu dari ini rusak dalam terjemahan, Anda mendapatkan error runtime atau markup yang rusak.

TranslateBot menginstruksikan model AI untuk mempertahankan semua format placeholder dan memvalidasi output. String seperti:

Welcome to %(site_name)s! You have <strong>%(count)d</strong> new messages.

Diterjemahkan ke bahasa Belanda sebagai:

Welkom bij %(site_name)s! Je hebt <strong>%(count)d</strong> nieuwe berichten.

Setiap placeholder tetap utuh.

Mengontrol Kualitas dengan TRANSLATING.md

Model AI menerjemahkan lebih baik ketika mereka memahami konteks. TranslateBot mencari file TRANSLATING.md di root proyek Anda dan menyertakan isinya di setiap permintaan terjemahan.

# Translation Context

## About This Project
A B2B project management tool for construction companies.

## Terminology
- "project" means a construction project, not a software project
- "plan" means a building plan/blueprint, not a subscription plan
- Keep "Gantt chart" as-is in all languages

## Tone
- German: use formal "Sie" form (business context)
- French: use formal "vous" form
- Dutch: use informal "je" form

## Do Not Translate
- Brand name: "BuildFlow"
- Feature names: "SmartSchedule", "CostTracker"

File ini dikontrol versi bersama kode Anda, sehingga seluruh tim berbagi konteks terjemahan yang sama. Anda juga dapat menempatkan file TRANSLATING.md per aplikasi untuk aplikasi dengan terminologi khusus. Modul rekam medis dan modul penagihan masing-masing bisa memiliki glosariumnya sendiri.

Pratinjau Sebelum Commit

Flag --dry-run menunjukkan persis apa yang akan diterjemahkan tanpa melakukan panggilan API atau memodifikasi file:

python manage.py translate --target-lang fr --dry-run
Found 15 untranslated entries
Dry run mode: skipping LLM translation

Would translate 'Welcome to our site'
Would translate 'Hello, %(name)s!'
...

Dry run complete: 15 entries would be translated

Ini berguna sebelum menjalankan terjemahan besar atau ketika anggota tim baru ingin memahami apa yang dilakukan perintah sebelum berkomitmen pada biaya API.

Integrasi CI/CD

Terjemahan menjadi usang tidak bisa dihindari tanpa penegakan. TranslateBot menyertakan management command check_translations yang dirancang untuk pipeline CI:

# .github/workflows/ci.yml
jobs:
  translations:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/setup-uv@v4
        with:
          enable-cache: true
      - run: uv python install
      - run: uv sync --frozen
      - name: Install gettext
        run: sudo apt-get update && sudo apt-get install -y --no-install-recommends gettext
      - name: Check translations
        run: uv run python manage.py check_translations --makemessages

Flag --makemessages menjalankan makemessages -a --no-obsolete terlebih dahulu, memastikan file .po mencerminkan kode sumber saat ini sebelum memeriksa. Jika ada entri yang belum diterjemahkan atau fuzzy, perintah keluar dengan kode 1 dan menggagalkan build:

locale/de/LC_MESSAGES/django.po: 2 untranslated, 0 fuzzy
locale/nl/LC_MESSAGES/django.po: 0 untranslated, 1 fuzzy
CommandError: Translation check failed

Alur kerja developer yang umum menjadi:

  1. Tambahkan string baru yang dapat diterjemahkan di branch fitur.
  2. CI gagal karena string tersebut belum diterjemahkan.
  3. Jalankan python manage.py translate secara lokal.
  4. Commit file .po yang diperbarui.
  5. CI berhasil.

Terjemahan tidak pernah diam-diam tidak sinkron.

Menerjemahkan Konten Database

Jika aplikasi Anda menyimpan konten yang dapat diterjemahkan di database (nama produk, judul posting blog, label kategori), TranslateBot juga terintegrasi dengan django-modeltranslation:

pip install translatebot-django[modeltranslation]
# Translate all registered model fields
python manage.py translate --target-lang de --models

# Translate specific models only
python manage.py translate --target-lang de --models Product Category

Logika inkremental yang sama berlaku: hanya field di mana nilai bahasa target kosong yang diterjemahkan.

Perbandingan Biaya

Salah satu pertanyaan paling umum adalah apakah terjemahan AI hemat biaya dibandingkan alternatif lain. Berikut perbandingan kasar untuk proyek dengan 500 string yang dapat diterjemahkan dalam 5 bahasa:

Pendekatan Perkiraan Biaya Investasi Waktu
Manual (waktu developer) $0 dari kantong, 20-40+ jam Sangat tinggi
Layanan terjemahan profesional $500-2.000+ Rendah (tapi lambat)
Platform lokalisasi SaaS $50-200/bulan Sedang
TranslateBot + GPT-4o-mini ~$0,05 (sekali) Menit
TranslateBot + DeepL Free $0 (hingga 500rb karakter/bulan) Menit
TranslateBot + Claude/GPT-4o ~$0,30 (sekali) Menit

Angka-angka berubah tergantung jumlah string dan bahasa target, tetapi perbedaan orde magnitudonya konsisten. Untuk pemeliharaan berkelanjutan (menerjemahkan 20-50 string baru yang ditambahkan setiap sprint), biaya AI pada dasarnya nol.

Praktik Terbaik

Mulai dengan --dry-run. Sebelum menjalankan terjemahan pertama yang sebenarnya, pratinjau apa yang akan terjadi. Ini membangun kepercayaan dan menangkap masalah konfigurasi lebih awal.

Commit file .po sebelum menerjemahkan. Jika ada yang salah, git checkout mengembalikan Anda ke kondisi bersih secara instan.

Tulis TRANSLATING.md sejak hari pertama. Bahkan file singkat dengan deskripsi proyek dan beberapa aturan terminologi secara terukur meningkatkan kualitas terjemahan.

Tambahkan check_translations ke CI. Langkah tunggal ini mencegah mode kegagalan i18n yang paling umum: string yang ditandai untuk diterjemahkan tetapi tidak pernah benar-benar diterjemahkan.

Gunakan gpt-4o-mini atau DeepL untuk efisiensi biaya. Simpan model premium seperti GPT-4o atau Claude untuk proyek di mana presisi penting, seperti copy marketing, teks hukum, atau terminologi khusus domain.

Review string kritis. Terjemahan AI cukup baik untuk sebagian besar teks UI, tetapi minta penutur asli untuk mereview apa pun yang mengikat secara hukum, kritis untuk keselamatan, atau berhadapan dengan pelanggan dalam konteks berisiko tinggi.

Dari Jam ke Detik

Framework i18n Django sangat baik dalam mengekstrak dan mengompilasi terjemahan. Kesenjangan selalu ada di langkah terjemahan itu sendiri, pekerjaan membosankan dan rawan kesalahan untuk mengisi ratusan nilai msgstr di berbagai bahasa.

TranslateBot menutup kesenjangan itu. Instal, arahkan ke provider AI, dan jalankan satu perintah. String baru diterjemahkan. String yang ada tetap tidak tersentuh. Placeholder tetap utuh. CI menangkap apa pun yang terlewat.

File .po Anda berhenti menjadi beban dan menjadi bagian biasa dari build.

pip install translatebot-django

Mulai di translatebot.dev.

Hentikan pengeditan file .po secara manual

TranslateBot mengotomatiskan terjemahan Django dengan AI. Satu perintah, semua bahasa Anda, biaya terjemahan yang sangat murah.