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:
- Placeholder rusak. Salin string seperti
Welcome, %(name)s!ke Google Translate, dan Anda sering mendapatkanWillkommen, %(Name)s!atauBienvenue, %(nom)s!. Kerusakan halus ini menyebabkan crash saat runtime. - Konsistensi menyimpang. Tanpa glosarium, "dashboard" diterjemahkan sebagai "Instrumententafel" di satu file dan "Dashboard" di file lain. Tiga bulan kemudian, tidak ada yang ingat mana yang disengaja.
- Sprint menambah string. Setiap branch fitur menambahkan string baru yang dapat diterjemahkan. Bahkan jika Anda membayar untuk terjemahan lengkap kuartal lalu, sekarang ada 40 entri yang belum diterjemahkan tersebar di file
.poAnda. - Asisten AI membantu sekali. Anda bisa menempelkan file
.poke ChatGPT atau Claude dan mendapatkan hasil yang layak. Tapi sprint berikutnya, ketika 15 string baru muncul, Anda membuat prompt dari awal, menerjemahkan ulang seluruh file, dan berharap tetap konsisten dengan yang sudah ada.
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 |
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:
- Biaya. Anda hanya membayar untuk string baru, bukan seluruh file.
- Kecepatan. Menerjemahkan 15 string membutuhkan detik, bukan menit.
- 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:
- Tambahkan string baru yang dapat diterjemahkan di branch fitur.
- CI gagal karena string tersebut belum diterjemahkan.
- Jalankan
python manage.py translatesecara lokal. - Commit file
.poyang diperbarui. - 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.