اگر تا به حال یک اپلیکیشن Django را به بیش از یک زبان منتشر کردهاید، این روند را میشناسید. رشتههای خود را در gettext() میپیچید، makemessages را اجرا میکنید، یک فایل .po با صدها ورودی باز میکنید و شروع به ترجمه خط به خط میکنید. برای دو زبان و پنجاه رشته، قابل تحمل است. برای شش زبان و پانصد رشته، یک روز کامل کاری است که هرگز آن را پس نمیگیرید.
این راهنما خط لوله بینالمللیسازی (i18n) Django را از ابتدا تا انتها پوشش میدهد، توضیح میدهد که کجا مشکلساز میشود و نشان میدهد چگونه بخش دردناک را با ترجمه مبتنی بر هوش مصنوعی خودکار کنید.
گردش کار استاندارد Django i18n
سیستم i18n داخلی Django به خوبی طراحی شده است. حلقه اصلی به این شکل است:
مرحله ۱: رشتهها را برای ترجمه علامتگذاری کنید در کد 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>
مرحله ۲: رشتهها را استخراج کنید در فایلهای .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 ""
مرحله ۳: هر msgstr خالی را ترجمه کنید به صورت دستی.
مرحله ۴: کامپایل کنید فایلهای .po تکمیلشده را به فایلهای باینری .mo:
python manage.py compilemessages
مراحل ۱، ۲ و ۴ سریع هستند. مرحله ۳ جایی است که فرآیند از هم میپاشد.
چرا ترجمه دستی مقیاسپذیر نیست
یک اپلیکیشن Django معمولی بین ۲۰۰ تا ۲,۰۰۰ رشته قابل ترجمه دارد. آن را در تعداد زبانهای هدف ضرب کنید و با یک تعهد زمانی جدی مواجه میشوید.
این یک شکایت نظری نیست. در یک تاپیک معروف Django Forum، یک توسعهدهنده گزارش داد که بیش از ۸ ساعت برای هر فایل .po صرف ترجمه دستی کرده است. یک مشارکتکننده اصلی Django توضیح داد که بیش از ۱۰ ساعت برای ادغام ترجمههای ارسالی جامعه در یک نسخه صرف کرده است، بیشتر برای بررسی، اصلاح قالببندی و رفع placeholderهای خراب.
مشکلات در طول زمان ترکیب میشوند:
- Placeholderها خراب میشوند. یک رشته مانند
Welcome, %(name)s!را در Google Translate کپی کنید، و اغلبWillkommen, %(Name)s!یاBienvenue, %(nom)s!برمیگردد. آن خرابی ظریف باعث خطاهای زمان اجرا میشود. - سازگاری از بین میرود. بدون واژهنامه، "dashboard" در یک فایل به عنوان "Instrumententafel" و در دیگری به عنوان "Dashboard" ترجمه میشود. سه ماه بعد، هیچکس به یاد نمیآورد که کدام عمدی بوده است.
- اسپرینتها رشته اضافه میکنند. هر شاخه ویژگی رشتههای قابل ترجمه جدید اضافه میکند. حتی اگر فصل گذشته هزینه یک دور کامل ترجمه را پرداخت کردهاید، اکنون ۴۰ ورودی ترجمهنشده در فایلهای
.poشما پراکنده شدهاند. - دستیاران AI یک بار کمک میکنند. میتوانید یک فایل
.poرا در ChatGPT یا Claude بچسبانید و نتایج مناسبی بگیرید. اما اسپرینت بعدی، وقتی ۱۵ رشته جدید ظاهر میشوند، دوباره از صفر پرامپت مینویسید، کل فایل را دوباره ترجمه میکنید و امیدوارید با آنچه قبلاً بود سازگار بماند.
علت اصلی این است که ترجمه به عنوان یک رویداد یکباره به جای یک فرآیند تدریجی و تکرارپذیر تلقی میشود.
خودکارسازی ترجمه با هوش مصنوعی
ایده ساده است: به جای اینکه یک انسان هر فایل .po را باز کند و مقادیر msgstr را پر کند، یک ابزار فایل را میخواند، رشتههای ترجمهنشده را به یک مدل AI یا API ترجمه ارسال میکند، نتایج را مینویسد و همه چیز دیگر (نظرات، ساختار فایل، placeholderها، فرمهای جمع) را حفظ میکند.
TranslateBot Django یک بسته متنباز است که دقیقاً همین کار را انجام میدهد. به سیستم فرمان مدیریت Django متصل میشود، بنابراین در گردش کاری که از قبل دارید جای میگیرد.
راهاندازی گام به گام
۱. نصب بسته
pip install translatebot-django
یا، اگر از uv استفاده میکنید (توصیهشده):
uv add --dev translatebot-django
نصب به عنوان وابستگی توسعه عمدی است. شما فقط هنگام تولید ترجمهها به TranslateBot نیاز دارید، نه در زمان اجرا در تولید.
۲. افزودن به INSTALLED_APPS
# settings.py
INSTALLED_APPS = [
# ...
"translatebot_django",
]
۳. پیکربندی ارائهدهنده AI
# settings.py
import os
TRANSLATEBOT_API_KEY = os.getenv("OPENAI_API_KEY")
TRANSLATEBOT_MODEL = "gpt-4o-mini"
TranslateBot در پشت صحنه از LiteLLM استفاده میکند، به این معنی که میتوانید با تغییر یک رشته، هر یک از بیش از ۱۰۰ مدل را جایگزین کنید:
| ارائهدهنده | مقدار 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 | به جای آن از TRANSLATEBOT_PROVIDER = "deepl" استفاده کنید |
برای DeepL، پکیج اضافی را نصب کنید: pip install translatebot-django[deepl]. سطح رایگان DeepL ماهانه ۵۰۰,۰۰۰ کاراکتر بدون هزینه در اختیار شما قرار میدهد که برای اکثر پروژههای کوچک تا متوسط کافی است.
۴. تعریف زبانها
# settings.py
LANGUAGES = [
("en", "English"),
("de", "German"),
("fr", "French"),
("nl", "Dutch"),
("ja", "Japanese"),
]
۵. اجرای ترجمه
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
۶. کامپایل طبق معمول
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 آنها خالی است. اگر ۵۰۰ رشته دارید و ۱۵ رشته در این اسپرینت جدید هستند، فقط آن ۱۵ رشته به API ارسال میشوند.
این به دلایل عملی اهمیت دارد:
- هزینه. فقط برای رشتههای جدید هزینه میپردازید، نه کل فایل.
- سرعت. ترجمه ۱۵ رشته ثانیهها طول میکشد، نه دقیقهها.
- ثبات. ترجمههایی که قبلاً بررسی و تأیید کردهاید هرگز بازنویسی نمیشوند (مگر اینکه صراحتاً
--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 شامل فرمان مدیریت 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 قبل از بررسی، کد منبع فعلی را منعکس میکنند. اگر ورودیهایی ترجمهنشده یا مبهم باشند، فرمان با کد ۱ خارج میشود و ساخت را شکست میدهد:
locale/de/LC_MESSAGES/django.po: 2 untranslated, 0 fuzzy
locale/nl/LC_MESSAGES/django.po: 0 untranslated, 1 fuzzy
CommandError: Translation check failed
گردش کار معمول توسعهدهنده به این شکل میشود:
- رشتههای قابل ترجمه جدید را در یک شاخه ویژگی اضافه کنید.
- CI شکست میخورد زیرا آن رشتهها ترجمهنشده هستند.
python manage.py translateرا به صورت محلی اجرا کنید.- فایلهای
.poبهروزشده را کامیت کنید. - 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 در مقایسه با جایگزینها مقرونبهصرفه است. در اینجا مقایسهای تقریبی برای پروژهای با ۵۰۰ رشته قابل ترجمه در ۵ زبان آمده است:
| رویکرد | هزینه تخمینی | سرمایهگذاری زمانی |
|---|---|---|
| دستی (زمان توسعهدهنده) | ۰ دلار از جیب، ۲۰-۴۰+ ساعت | بسیار بالا |
| خدمات ترجمه حرفهای | ۵۰۰-۲,۰۰۰+ دلار | کم (اما بازگشت کند) |
| پلتفرم بومیسازی SaaS | ۵۰-۲۰۰ دلار/ماه | متوسط |
| TranslateBot + GPT-4o-mini | ~۰.۰۵ دلار (یکبار) | دقیقهها |
| TranslateBot + DeepL Free | ۰ دلار (تا ۵۰۰ هزار کاراکتر/ماه) | دقیقهها |
| TranslateBot + Claude/GPT-4o | ~۰.۳۰ دلار (یکبار) | دقیقهها |
اعداد بسته به تعداد رشته و زبانهای هدف تغییر میکنند، اما تفاوت مرتبه بزرگی ثابت است. برای نگهداری مداوم (ترجمه ۲۰-۵۰ رشته جدید اضافهشده در هر اسپرینت)، هزینه AI اساساً صفر است.
بهترین شیوهها
با --dry-run شروع کنید. قبل از اولین دور واقعی ترجمه، پیشنمایش کنید که چه اتفاقی میافتد. این اعتماد ایجاد میکند و مشکلات پیکربندی را زود شناسایی میکند.
قبل از ترجمه فایلهای .po را کامیت کنید. اگر مشکلی پیش آمد، git checkout فوراً شما را به حالت تمیز برمیگرداند.
از روز اول TRANSLATING.md بنویسید. حتی یک فایل کوتاه با توضیحات پروژه و چند قاعده اصطلاحی به طور قابل اندازهگیری کیفیت ترجمه را بهبود میبخشد.
check_translations را به CI اضافه کنید. این تک مرحله از رایجترین حالت شکست i18n جلوگیری میکند: رشتههایی که برای ترجمه علامتگذاری شدهاند اما هرگز واقعاً ترجمه نشدهاند.
برای بهرهوری هزینه از gpt-4o-mini یا DeepL استفاده کنید. مدلهای ممتاز مانند GPT-4o یا Claude را برای پروژههایی نگه دارید که دقت اهمیت دارد، مانند متن بازاریابی، متن حقوقی یا اصطلاحات تخصصی دامنه.
رشتههای حیاتی را بررسی کنید. ترجمههای AI برای اکثر متون رابط کاربری به اندازه کافی خوب هستند، اما هر چیزی که از نظر حقوقی الزامآور، حیاتی از نظر ایمنی یا در یک زمینه پرخطر رو به مشتری باشد را توسط یک گویشور بومی بررسی کنید.
از ساعتها به ثانیهها
فریمورک i18n Django در استخراج و کامپایل ترجمهها عالی است. شکاف همیشه در خود مرحله ترجمه بوده است، کار خستهکننده و مستعد خطای پر کردن صدها مقدار msgstr در چندین زبان.
TranslateBot آن شکاف را پر میکند. نصب کنید، به یک ارائهدهنده AI اشاره کنید و یک فرمان اجرا کنید. رشتههای جدید ترجمه میشوند. رشتههای موجود دستنخورده میمانند. Placeholderها سالم باقی میمانند. CI هر چیزی که از دست برود را میگیرد.
فایلهای .po شما دیگر یک کار طاقتفرسا نیستند و به بخشی دیگر از ساخت تبدیل میشوند.
pip install translatebot-django
در translatebot.dev شروع کنید.