กลับไปยังบล็อก

Django i18n: คู่มือฉบับสมบูรณ์สำหรับการทำให้การแปลไฟล์ .po เป็นอัตโนมัติ

2026-01-28 อ่าน 5 นาที
Django i18n: คู่มือฉบับสมบูรณ์สำหรับการทำให้การแปลไฟล์ .po เป็นอัตโนมัติ

หากคุณเคยปล่อยแอป Django ในมากกว่าหนึ่งภาษา คุณย่อมรู้ขั้นตอนนี้ดี คุณห่อสตริงด้วย gettext() รัน makemessages เปิดไฟล์ .po ที่มีรายการหลายร้อยรายการ และเริ่มแปลทีละบรรทัด สำหรับสองภาษาและห้าสิบสตริง ยังพอทนได้ สำหรับหกภาษาและห้าร้อยสตริง มันคือหนึ่งวันทำงานเต็มที่คุณจะไม่มีวันได้กลับคืน

คู่มือนี้ครอบคลุมไปป์ไลน์การทำให้เป็นสากล (i18n) ของ Django ตั้งแต่ต้นจนจบ อธิบายว่ามันพังตรงไหน และแสดงวิธีอัตโนมัติส่วนที่เจ็บปวดด้วยการแปลที่ขับเคลื่อนด้วย AI

เวิร์กโฟลว์ Django i18n มาตรฐาน

ระบบ i18n ในตัวของ Django ได้รับการออกแบบมาอย่างดี ลูปหลักมีลักษณะดังนี้:

ขั้นตอนที่ 1: ทำเครื่องหมายสตริงสำหรับการแปล ในโค้ด Python และเทมเพลต:

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>

ขั้นตอนที่ 2: ดึงสตริง ไปยังไฟล์ .po:

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

คำสั่งนี้สแกนโค้ดเบสทั้งหมดและสร้างไฟล์ .po หนึ่งไฟล์ต่อภาษา ซึ่งมีสตริงที่แปลได้ทุกตัว:

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

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

ขั้นตอนที่ 3: แปลทุก msgstr ที่ว่างเปล่า ด้วยมือ

ขั้นตอนที่ 4: คอมไพล์ ไฟล์ .po ที่เสร็จแล้วเป็นไฟล์ไบนารี .mo:

python manage.py compilemessages

ขั้นตอนที่ 1, 2 และ 4 รวดเร็ว ขั้นตอนที่ 3 คือจุดที่กระบวนการพังทลาย

ทำไมการแปลด้วยมือจึงไม่สามารถขยายขนาดได้

แอปพลิเคชัน Django ทั่วไปมีสตริงที่แปลได้ราว 200 ถึง 2,000 ตัว คูณจำนวนนั้นด้วยจำนวนภาษาเป้าหมาย แล้วคุณจะเห็นว่าต้องใช้เวลามากแค่ไหน

นี่ไม่ใช่คำบ่นทางทฤษฎี ในกระทู้ Django Forum ที่เป็นที่รู้จัก นักพัฒนาคนหนึ่งรายงานว่าใช้เวลากว่า 8 ชั่วโมงต่อไฟล์ .po ในการแปลด้วยมือ ผู้มีส่วนร่วมหลักของ Django อธิบายว่าใช้เวลากว่า 10 ชั่วโมงในการรวมคำแปลที่ชุมชนส่งมาในรีลีสเดียว ส่วนใหญ่ในการตรวจสอบ แก้ไขการจัดรูปแบบ และแก้ไข placeholder ที่เสียหาย

ปัญหาสะสมตามเวลา:

สาเหตุหลักคือการแปลถูกมองเป็นเหตุการณ์ครั้งเดียวแทนที่จะเป็นกระบวนการที่เป็นขั้นตอนและทำซ้ำได้

อัตโนมัติการแปลด้วย AI

แนวคิดนี้ตรงไปตรงมา: แทนที่คนจะเปิดแต่ละไฟล์ .po และกรอกค่า msgstr เครื่องมือจะอ่านไฟล์ ส่งสตริงที่ยังไม่ได้แปลไปยังโมเดล AI หรือ API แปลภาษา เขียนผลลัพธ์กลับ และรักษาทุกอย่างอื่น (ความคิดเห็น โครงสร้างไฟล์ placeholder รูปแบบพหูพจน์) ไว้

TranslateBot Django เป็นแพ็คเกจโอเพนซอร์สที่ทำสิ่งนี้อย่างแม่นยำ มันเชื่อมต่อกับระบบ management command ของ Django จึงเข้ากับเวิร์กโฟลว์ที่คุณมีอยู่แล้ว

การตั้งค่าทีละขั้นตอน

1. ติดตั้งแพ็คเกจ

pip install translatebot-django

หรือหากคุณใช้ uv (แนะนำ):

uv add --dev translatebot-django

การติดตั้งเป็น dev dependency เป็นไปโดยเจตนา คุณต้องการ TranslateBot เฉพาะเมื่อสร้างคำแปล ไม่ใช่ขณะรันไทม์ในโปรดักชัน

2. เพิ่มลงใน INSTALLED_APPS

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

3. กำหนดค่าผู้ให้บริการ AI

# settings.py
import os

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

TranslateBot ใช้ LiteLLM ภายใน ซึ่งหมายความว่าคุณสามารถสลับโมเดลใดก็ได้จากกว่า 100 โมเดลด้วยการเปลี่ยนสตริงเดียว:

ผู้ให้บริการ ค่า 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 ใช้ TRANSLATEBOT_PROVIDER = "deepl" แทน

สำหรับ DeepL ให้ติดตั้งส่วนเสริม: pip install translatebot-django[deepl] ระดับฟรีของ DeepL ให้คุณ 500,000 ตัวอักษรต่อเดือนโดยไม่มีค่าใช้จ่าย ซึ่งเพียงพอสำหรับโปรเจกต์ขนาดเล็กถึงกลางส่วนใหญ่

4. กำหนดภาษาของคุณ

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

5. เรียกใช้การแปล

python manage.py translate

เท่านี้เอง TranslateBot สแกนโปรเจกต์ของคุณหาไฟล์ .po ระบุรายการที่ยังไม่ได้แปล ส่งไปยังโมเดล AI ที่กำหนดค่าไว้ในแบตช์ที่ปรับให้เหมาะสม และเขียนผลลัพธ์กลับ คำแปลที่มีอยู่จะไม่ถูกแตะต้อง

เพื่อแปลภาษาเดียว:

python manage.py translate --target-lang nl

ผลลัพธ์จะมีลักษณะดังนี้:

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

6. คอมไพล์ตามปกติ

python manage.py compilemessages

เวิร์กโฟลว์เต็มรูปแบบของคุณตอนนี้คือ:

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

สามคำสั่ง ทุกภาษา ทุกสปรินต์

แบบเพิ่มทีละน้อยตั้งแต่ออกแบบ

คุณสมบัติที่สำคัญที่สุดสำหรับเวิร์กโฟลว์ที่ทำซ้ำได้คือการแปลแบบเพิ่มทีละน้อย TranslateBot แปลเฉพาะรายการที่ msgstr ว่างเปล่า หากคุณมี 500 สตริงและ 15 เป็นสตริงใหม่ในสปรินต์นี้ เฉพาะ 15 นั้นจะถูกส่งไปยัง API

สิ่งนี้สำคัญด้วยเหตุผลเชิงปฏิบัติ:

  1. ค่าใช้จ่าย คุณจ่ายเฉพาะสตริงใหม่ ไม่ใช่ทั้งไฟล์
  2. ความเร็ว การแปล 15 สตริงใช้เวลาเพียงวินาที ไม่ใช่นาที
  3. ความเสถียร คำแปลที่คุณตรวจสอบและอนุมัติแล้วจะไม่ถูกเขียนทับ (เว้นแต่คุณจะส่ง --overwrite อย่างชัดเจน)

ความปลอดภัยของ Placeholder

Django ใช้รูปแบบ placeholder หลายรูปแบบ: %(name)s, %s, %d, {0}, {name} และแท็ก HTML แบบอินไลน์เช่น <strong> หรือ <a href="..."> หากรูปแบบใดรูปแบบหนึ่งถูกทำให้เสียหายในการแปล คุณจะได้ข้อผิดพลาดขณะรันไทม์หรือมาร์กอัปที่เสียหาย

TranslateBot สั่งโมเดล AI ให้รักษารูปแบบ placeholder ทั้งหมดและตรวจสอบผลลัพธ์ สตริงเช่น:

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

แปลเป็นภาษาดัตช์ว่า:

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

ทุก placeholder ยังคงอยู่ครบถ้วน

ควบคุมคุณภาพด้วย TRANSLATING.md

โมเดล AI แปลได้ดีขึ้นเมื่อเข้าใจบริบท TranslateBot ค้นหาไฟล์ TRANSLATING.md ในรูทของโปรเจกต์และรวมเนื้อหาในทุกคำขอแปล

# 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"

ไฟล์นี้ถูกควบคุมเวอร์ชันร่วมกับโค้ดของคุณ ดังนั้นทั้งทีมจะใช้บริบทการแปลเดียวกัน คุณยังสามารถวางไฟล์ TRANSLATING.md สำหรับแต่ละแอปที่มีคำศัพท์เฉพาะทาง โมดูลเวชระเบียนและโมดูลการเรียกเก็บเงินสามารถมีคำศัพท์เฉพาะของตัวเอง

ดูตัวอย่างก่อนคอมมิต

แฟล็ก --dry-run แสดงให้เห็นว่าจะแปลอะไรโดยไม่ทำการเรียก API หรือแก้ไขไฟล์:

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

สิ่งนี้มีประโยชน์ก่อนการแปลจำนวนมากหรือเมื่อรับสมาชิกทีมใหม่ที่ต้องการเข้าใจว่าคำสั่งทำอะไรก่อนที่จะตกลงกับค่าใช้จ่าย API

การรวม CI/CD

คำแปลที่เก่าเป็นสิ่งที่หลีกเลี่ยงไม่ได้หากไม่มีการบังคับใช้ TranslateBot มี management command check_translations ที่ออกแบบมาสำหรับไปป์ไลน์ 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

แฟล็ก --makemessages จะรัน makemessages -a --no-obsolete ก่อน เพื่อให้แน่ใจว่าไฟล์ .po สะท้อนซอร์สโค้ดปัจจุบันก่อนตรวจสอบ หากมีรายการที่ยังไม่ได้แปลหรือ fuzzy คำสั่งจะออกด้วยรหัส 1 และทำให้บิลด์ล้มเหลว:

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

เวิร์กโฟลว์ปกติของนักพัฒนากลายเป็น:

  1. เพิ่มสตริงที่แปลได้ใหม่ใน feature branch
  2. CI ล้มเหลวเพราะสตริงเหล่านั้นยังไม่ได้แปล
  3. รัน python manage.py translate ในเครื่อง
  4. คอมมิตไฟล์ .po ที่อัปเดตแล้ว
  5. CI ผ่าน

คำแปลจะไม่มีวันหลุดจากการซิงก์อย่างเงียบๆ

การแปลเนื้อหาฐานข้อมูล

หากแอปพลิเคชันของคุณเก็บเนื้อหาที่แปลได้ในฐานข้อมูล (ชื่อผลิตภัณฑ์ หัวข้อบล็อกโพสต์ ป้ายกำกับหมวดหมู่) TranslateBot ยังรวมเข้ากับ 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

ตรรกะแบบเพิ่มทีละน้อยเดียวกันนี้ใช้ได้: เฉพาะฟิลด์ที่ค่าภาษาเป้าหมายว่างเปล่าเท่านั้นที่จะถูกแปล

การเปรียบเทียบค่าใช้จ่าย

หนึ่งในคำถามที่พบบ่อยที่สุดคือการแปลด้วย AI คุ้มค่าเมื่อเทียบกับทางเลือกอื่นหรือไม่ นี่คือการเปรียบเทียบคร่าวๆ สำหรับโปรเจกต์ที่มี 500 สตริงที่แปลได้ใน 5 ภาษา:

แนวทาง ค่าใช้จ่ายโดยประมาณ การลงทุนด้านเวลา
ด้วยมือ (เวลาของนักพัฒนา) $0 จากกระเป๋า, 20-40+ ชั่วโมง สูงมาก
บริการแปลภาษามืออาชีพ $500-2,000+ ต่ำ (แต่ใช้เวลานาน)
แพลตฟอร์มแปลภาษา SaaS $50-200/เดือน ปานกลาง
TranslateBot + GPT-4o-mini ~$0.05 (ครั้งเดียว) นาที
TranslateBot + DeepL Free $0 (สูงสุด 500k ตัวอักษร/เดือน) นาที
TranslateBot + Claude/GPT-4o ~$0.30 (ครั้งเดียว) นาที

ตัวเลขเปลี่ยนแปลงตามจำนวนสตริงและภาษาเป้าหมาย แต่ความแตกต่างระดับลำดับความสำคัญยังคงสม่ำเสมอ สำหรับการบำรุงรักษาต่อเนื่อง (การแปล 20-50 สตริงใหม่ที่เพิ่มในแต่ละสปรินต์) ค่าใช้จ่าย AI แทบจะเป็นศูนย์

แนวปฏิบัติที่ดีที่สุด

เริ่มด้วย --dry-run ก่อนการแปลจริงครั้งแรก ดูตัวอย่างว่าจะเกิดอะไรขึ้น สิ่งนี้สร้างความมั่นใจและตรวจจับปัญหาการกำหนดค่าตั้งแต่เนิ่นๆ

คอมมิตไฟล์ .po ก่อนแปล หากมีอะไรผิดพลาด git checkout จะพาคุณกลับสู่สถานะสะอาดทันที

เขียน TRANSLATING.md ตั้งแต่วันแรก แม้แต่ไฟล์สั้นๆ ที่มีคำอธิบายโปรเจกต์และกฎคำศัพท์สองสามข้อก็ช่วยปรับปรุงคุณภาพการแปลได้อย่างวัดผลได้

เพิ่ม check_translations ลงใน CI ขั้นตอนเดียวนี้ป้องกันโหมดความล้มเหลว i18n ที่พบบ่อยที่สุด: สตริงที่ถูกทำเครื่องหมายสำหรับการแปลแต่ไม่เคยถูกแปลจริง

ใช้ gpt-4o-mini หรือ DeepL เพื่อประสิทธิภาพด้านต้นทุน เก็บโมเดลพรีเมียมอย่าง GPT-4o หรือ Claude ไว้สำหรับโปรเจกต์ที่ต้องการความแม่นยำ เช่น ข้อความการตลาด ข้อความทางกฎหมาย หรือคำศัพท์เฉพาะทาง

ตรวจสอบสตริงที่สำคัญ คำแปลจาก AI ดีพอสำหรับข้อความ UI ส่วนใหญ่ แต่ให้ผู้พูดภาษาแม่ตรวจสอบสิ่งที่มีผลผูกพันทางกฎหมาย สำคัญต่อความปลอดภัย หรือเผชิญหน้ากับลูกค้าในบริบทที่มีความเสี่ยงสูง

จากชั่วโมงเป็นวินาที

เฟรมเวิร์ก i18n ของ Django เป็นเลิศในการดึงและคอมไพล์คำแปล ช่องว่างอยู่ที่ขั้นตอนการแปลเสมอ งานที่น่าเบื่อและเสี่ยงต่อข้อผิดพลาดในการกรอกค่า msgstr หลายร้อยค่าในหลายภาษา

TranslateBot ปิดช่องว่างนั้น ติดตั้ง ชี้ไปที่ผู้ให้บริการ AI และรันคำสั่งเดียว สตริงใหม่ได้รับการแปล สตริงที่มีอยู่ไม่ถูกแตะต้อง Placeholder ยังคงอยู่ครบถ้วน CI จับทุกอย่างที่หลุด

ไฟล์ .po ของคุณหยุดเป็นงานที่น่าเบื่อและกลายเป็นเพียงส่วนหนึ่งของบิลด์

pip install translatebot-django

เริ่มต้นที่ translatebot.dev

หยุดแก้ไขไฟล์ .po ด้วยตนเอง

TranslateBot ช่วยแปลภาษา Django อัตโนมัติด้วย AI เพียงคำสั่งเดียว ครอบคลุมทุกภาษา ค่าใช้จ่ายน้อยมาก