اگر با فریمورک بینالمللیسازی (i18n) داخلی Django کار کردهاید، میدانید که رشتههای ثابت را به خوبی مدیریت میکند. قرار دادن متن در gettext() یا استفاده از تگ قالب {% trans %} رشتهها را به فایلهای .po استخراج میکند و مترجمان آنها را تکمیل میکنند. این سیستم آزمایش شده و برای کد و قالبها عالی کار میکند.
اما محتوایی که در پایگاه داده شما ذخیره شده چطور؟
نام محصولات، عناوین مقالات، توضیحات دستهبندیها، پاسخهای سوالات متداول، محتوای تولید شده توسط کاربر. هیچکدام از اینها در کد منبع شما وجود ندارد. دستور makemessages در Django هرگز آنها را پیدا نمیکند و فایلهای .po نمیتوانند به شما کمکی کنند. اگر برنامه شما محتوای پویا را به کاربران در چندین زبان ارائه میدهد، به استراتژی متفاوتی نیاز دارید.
روش کار به این صورت است: از django-modeltranslation برای افزودن فیلدهای قابل ترجمه به مدلهای خود استفاده کنید، سپس ترجمه را با هوش مصنوعی با استفاده از TranslateBot خودکار کنید.
بستههای ترجمه پایگاه داده Django
چندین بسته شخص ثالث مشکل ترجمه پایگاه داده را حل میکنند، هر کدام با معماری متفاوت.
django-modeltranslation
ستونهای مخصوص هر زبان را مستقیماً به جداول موجود شما اضافه میکند. یک فیلد title به title_en، title_de، title_fr و غیره تبدیل میشود. کوئریها سریع هستند زیرا همه چیز در یک جدول است. رابط مدیریت همه زبانها را کنار هم نشان میدهد.
- مزایا: بدون JOIN، کوئریهای سریع، دسترسی شفاف از طریق توصیفگرهای فیلد، اکوسیستم بالغ
- معایب: تغییرات اسکیما برای هر زبان جدید، جداول عریضتر
django-parler
برای هر مدل یک جدول ترجمه جداگانه ایجاد میکند. جدول اصلی تمیز میماند و ترجمهها در جدول مرتبط از طریق کلید خارجی ذخیره میشوند.
- مزایا: اسکیمای تمیز، افزودن آسان زبانها بدون مهاجرت
- معایب: نیاز به JOIN برای محتوای ترجمه شده، الگوهای کوئری کمی پیچیدهتر
django-translations
از یک جدول ترجمه واحد با کلید خارجی عمومی استفاده میکند که به هر مدلی اشاره میکند. تمام ترجمهها برای تمام مدلها در یک جدول قرار میگیرند.
- مزایا: حداقل تغییرات اسکیما، کار با هر مدلی
- معایب: کوئریهای کلید خارجی عمومی میتوانند کند باشند، API کمتر شفاف
فیلد JSON دستی
میتوانید ترجمهها را در یک JSONField ذخیره کنید:
class Product(models.Model):
name_translations = models.JSONField(default=dict)
# {"en": "Running Shoes", "de": "Laufschuhe", "fr": "Chaussures de course"}
- مزایا: بدون وابستگی اضافی، انعطافپذیر
- معایب: بدون یکپارچگی ORM، بدون پشتیبانی مدیریت، همه چیز دستی
از کدام یک باید استفاده کنید؟
برای اکثر پروژهها، django-modeltranslation بهترین انتخاب است. بالغترین بسته است، بهترین یکپارچگی با مدیریت Django را دارد و تمام دادهها را برای کوئریهای سریع در یک جدول نگه میدارد. مبادله (جداول عریضتر و یک مهاجرت برای هر زبان جدید) برای اکثریت قریب به اتفاق برنامهها قابل مدیریت است. بقیه این راهنما از django-modeltranslation استفاده میکند.
راهاندازی django-modeltranslation قدم به قدم
مرحله ۱: نصب بسته
TranslateBot بسته django-modeltranslation را به عنوان وابستگی اختیاری همراه دارد. هر دو را یکجا نصب کنید:
pip install translatebot-django[modeltranslation]
یا اگر از uv استفاده میکنید:
uv add --dev translatebot-django[modeltranslation]
مرحله ۲: پیکربندی تنظیمات Django
دو چیز در settings.py مهم است: ترتیب اپلیکیشنها و لیست زبانها.
# settings.py
INSTALLED_APPS = [
'modeltranslation', # Must be BEFORE django.contrib.admin
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# Your apps
'shop',
'translatebot_django',
]
LANGUAGE_CODE = 'en'
LANGUAGES = [
('en', 'English'),
('de', 'German'),
('fr', 'French'),
('nl', 'Dutch'),
]
اپلیکیشن modeltranslation باید قبل از django.contrib.admin قرار گیرد تا بتواند کلاسهای مدیریت را برای نمایش فیلدهای ترجمه وصله کند.
مرحله ۳: ثبت مدلها برای ترجمه
در هر اپلیکیشنی که مدلهای قابل ترجمه دارد، یک فایل translation.py ایجاد کنید. برای یک اپلیکیشن فروشگاه تجارت الکترونیکی:
# shop/translation.py
from modeltranslation.translator import register, TranslationOptions
from .models import Product, Category
@register(Product)
class ProductTranslationOptions(TranslationOptions):
fields = ('name', 'description', 'short_description')
@register(Category)
class CategoryTranslationOptions(TranslationOptions):
fields = ('name', 'description')
فقط فیلدهایی را شامل کنید که متن قابل خواندن توسط انسان دارند. فیلدهایی مانند slug، price یا sku را ثبت نکنید.
مرحله ۴: ایجاد و اجرای مهاجرتها
python manage.py makemigrations
python manage.py migrate
پس از این، جدول shop_product شما ستونهای جدیدی دارد:
| Column | Type |
|---|---|
name |
varchar(200) |
name_en |
varchar(200) |
name_de |
varchar(200) |
name_fr |
varchar(200) |
name_nl |
varchar(200) |
description |
text |
description_en |
text |
description_de |
text |
description_fr |
text |
description_nl |
text |
short_description |
text |
short_description_en |
text |
short_description_de |
text |
short_description_fr |
text |
short_description_nl |
text |
هر زبانی که در LANGUAGES تعریف کردهاید، ستون مخصوص خود را برای هر فیلد ثبت شده دریافت میکند.
مشکل: فیلدهای ترجمه خالی
اکنون اسکیما آماده است، اما هر ستون _de، _fr و _nl خالی است. اگر ۵۰۰ محصول با ۳ فیلد قابل ترجمه و ۳ زبان مقصد دارید، ۴,۵۰۰ فیلد خالی منتظر تکمیل هستند.
ترجمه دستی این محتوا واقعبینانه نیست. حتی با یک سرویس ترجمه حرفهای، باید دادهها را صادر کنید، ارسال کنید، منتظر تحویل بمانید و نتایج را بازگردانید. برای یک تیم کوچک یا توسعهدهنده تنها، این معمولاً به این معنی است که قابلیت هرگز عرضه نمیشود.
اینجاست که TranslateBot وارد میشود.
خودکارسازی ترجمهها با TranslateBot
دستور مدیریت translate در TranslateBot میتواند تمام فیلدهای خالی را با استفاده از هوش مصنوعی پر کند. ابتدا کلید API خود را پیکربندی کنید:
# settings.py
TRANSLATEBOT_API_KEY = os.getenv("OPENAI_API_KEY")
TRANSLATEBOT_MODEL = "gpt-4o-mini" # Fast and cost-effective
سپس تمام مدلهای ثبت شده را به یک زبان مقصد ترجمه کنید:
python manage.py translate --target-lang de --models
این تک دستور هر مدل ثبت شده در django-modeltranslation را پیدا میکند، فیلدهایی که برای زبان مقصد خالی هستند را شناسایی میکند و آنها را با ترجمههای تولید شده توسط هوش مصنوعی پر میکند.
ترجمه مدلهای خاص
اگر فقط میخواهید محصولات را ترجمه کنید و نه دستهبندیها:
python manage.py translate --target-lang de --models Product
یا چندین مدل خاص:
python manage.py translate --target-lang de --models Product Category
پیشنمایش با اجرای آزمایشی
همیشه قبل از نوشتن در پایگاه داده، پیشنمایش ببینید:
python manage.py translate --target-lang de --models --dry-run
این به شما نشان میدهد که دقیقاً چه چیزی ترجمه خواهد شد بدون اینکه رکوردی تغییر کند.
ترجمه مجدد محتوای موجود
به طور پیشفرض، TranslateBot فیلدهایی که از قبل ترجمه دارند را رد میکند. برای بازنویسی ترجمههای موجود (مثلاً بعد از بهبود مدل هوش مصنوعی یا افزودن زمینه):
python manage.py translate --target-lang de --models --overwrite
ترجمه همه زبانها به صورت یکجا
اگر --target-lang را حذف کنید و LANGUAGES در تنظیمات شما تعریف شده باشد، TranslateBot به تمام زبانهای پیکربندی شده ترجمه میکند:
python manage.py translate --models
نحوه عملکرد خط لوله ترجمه
هنگام اجرای دستور ترجمه، موارد زیر اتفاق میافتد.
-
کشف. TranslateBot رجیستری django-modeltranslation را جستجو میکند تا تمام مدلهای ثبت شده و فیلدهای قابل ترجمه آنها را پیدا کند.
-
تشخیص منبع. برای هر رکورد، محتوای منبع را میخواند. ابتدا فیلد پایه (مثلاً
name) را بررسی میکند، سپس به اولین فیلد مخصوص زبان که پر شده (مثلاًname_en) بازمیگردد. رکوردهایی که محتوای منبع ندارند رد میشوند. -
دستهبندی. رکوردها در دستهها گروهبندی شده و به ارائهدهنده هوش مصنوعی ارسال میشوند. این کار فراخوانیهای API را کارآمد نگه میدارد و از رسیدن به محدودیت نرخ جلوگیری میکند.
-
ترجمه. هر دسته با استفاده از مدل هوش مصنوعی پیکربندی شده ترجمه میشود. میتوانید از هر ارائهدهنده LLM که توسط LiteLLM پشتیبانی میشود (OpenAI، Anthropic، Google، Azure و بسیاری دیگر) یا DeepL استفاده کنید.
-
نوشتن اتمیک. تمام بهروزرسانیهای پایگاه داده برای یک اجرای ترجمه در یک تراکنش واحد بستهبندی میشوند. اگر مشکلی پیش بیاید، مانند خطای API یا نقض محدودیت پایگاه داده، هیچ داده ناقصی ذخیره نمیشود. همه یا هیچ.
مثال کامل گردش کار
یک مثال کامل از تعریف مدل تا محتوای ترجمه شده، با استفاده از مدل Product تجارت الکترونیکی.
تعریف مدل
# shop/models.py
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=200)
description = models.TextField()
short_description = models.CharField(max_length=500, blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
sku = models.CharField(max_length=50, unique=True)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
ثبت برای ترجمه
# shop/translation.py
from modeltranslation.translator import register, TranslationOptions
from .models import Product
@register(Product)
class ProductTranslationOptions(TranslationOptions):
fields = ('name', 'description', 'short_description')
اجرای مهاجرتها
python manage.py makemigrations shop
python manage.py migrate
افزودن زمینه ترجمه (اختیاری)
یک فایل TRANSLATING.md در ریشه پروژه خود ایجاد کنید تا به هوش مصنوعی زمینهای درباره حوزه محصول شما بدهد:
# Translation Context
## About This Project
E-commerce store for outdoor sports equipment.
## Terminology
- "trail runners" refers to trail running shoes, not people
- Keep brand names (Nike, Salomon, Arc'teryx) untranslated
- "Gore-Tex" is a brand name, do not translate
## Tone
- Use informal "du" form in German
- Product descriptions should sound enthusiastic but not exaggerated
ترجمه
# Preview first
python manage.py translate --target-lang de --models Product --dry-run
# Apply translations
python manage.py translate --target-lang de --models Product
خروجی:
Translating Product model fields to German (de)...
Found 142 products with untranslated fields
Translating batch 1/15...
Translating batch 2/15...
...
Translating batch 15/15...
Successfully translated 142 products
تأیید در پنل مدیریت
پنل مدیریت Django را باز کنید و به هر محصولی بروید. فیلدهای ترجمه پر شده را خواهید دید:
- Name [de]: Ultraleichte Trail-Laufschuhe
- Description [de]: Diese leichten Trail-Laufschuhe bieten hervorragenden Grip...
- Short description [de]: Leicht, schnell und griffig auf jedem Untergrund.
برای هر زبان مقصد تکرار کنید:
python manage.py translate --target-lang fr --models Product
python manage.py translate --target-lang nl --models Product
یا همه زبانها را یکجا ترجمه کنید:
python manage.py translate --models Product
بهترین شیوهها
قبل از اجرای ترجمههای انبوه در محیط تولید، از پایگاه داده خود نسخه پشتیبان تهیه کنید. TranslateBot از تراکنشهای اتمیک استفاده میکند، بنابراین اجرای ناموفق داده ناقصی به جا نمیگذارد. اما داشتن نسخه پشتیبان راهی برای بازگشت فراهم میکند اگر کیفیت ترجمه مطابق انتظار شما نباشد.
# PostgreSQL example
pg_dump mydb > backup_before_translation.sql
ابتدا اجرای آزمایشی انجام دهید. همیشه قبل از اعمال ترجمهها به مدل یا زبان جدید، با --dry-run اجرا کنید. خروجی را بررسی کنید تا مطمئن شوید محتوای منبع به درستی شناسایی شده و ترجمهها منطقی به نظر میرسند.
برای پایگاههای داده بزرگ، هر بار یک مدل را ترجمه کنید. این کار بررسی نتایج و اجرای مجدد مدلهای خاص در صورت نیاز را آسانتر میکند.
python manage.py translate --target-lang de --models Product
python manage.py translate --target-lang de --models Category
python manage.py translate --target-lang de --models Article
زمینه ترجمه اضافه کنید. یک فایل TRANSLATING.md با اصطلاحات خاص حوزه و دستورالعملهای لحن، کیفیت ترجمه را به طور قابل توجهی بهبود میبخشد. این امر به ویژه برای حوزههای تخصصی مانند پزشکی، حقوق یا محصولات فنی مهم است.
زبان منبع خود را همیشه پر نگه دارید. TranslateBot از فیلد پایه یا فیلد زبان منبع میخواند. مطمئن شوید که گردش کار ورود داده شما همیشه زبان منبع را پر میکند. فیلدهای منبع خالی یعنی ترجمههای خالی.
برای پوشش کامل، با ترجمه فایل PO ترکیب کنید. هم رشتههای کد و هم محتوای پایگاه داده را ترجمه کنید:
# Static strings in code and templates
python manage.py makemessages -l de -l fr -l nl
python manage.py translate
python manage.py compilemessages
# Dynamic content in the database
python manage.py translate --models
به این ترتیب هر رشتهای که کاربران شما میبینند، چه از قالب باشد چه از پایگاه داده، ترجمه شده است.
مراحل بعدی
- مرجع دستورات کامل را برای تمام گزینههای موجود بخوانید
- یکپارچگی CI را راهاندازی کنید تا ترجمههای گمشده را به طور خودکار بررسی کنید
- مدلهای هوش مصنوعی پشتیبانی شده را بررسی کنید تا بهترین تعادل بین کیفیت و هزینه را برای پروژه خود پیدا کنید