إذا كنت قد عملت مع إطار عمل التدويل (i18n) المدمج في Django، فأنت تعلم أنه يتعامل مع السلاسل النصية الثابتة بشكل جيد. لف النص في gettext() أو استخدام وسم القالب {% trans %} يستخرج السلاسل النصية إلى ملفات .po، التي يملأها المترجمون. النظام مُجرب في المعارك ويعمل بشكل رائع للكود والقوالب.
لكن ماذا عن المحتوى المخزن في قاعدة بياناتك؟
أسماء المنتجات، عناوين المقالات، أوصاف الفئات، إجابات الأسئلة الشائعة، المحتوى الذي ينشئه المستخدمون. لا شيء من هذا موجود في الكود المصدري. أمر makemessages في Django لن يجده أبدًا، وملفات .po لا يمكنها مساعدتك هنا. إذا كان تطبيقك يقدم محتوى ديناميكيًا للمستخدمين بلغات متعددة، فأنت بحاجة إلى استراتيجية مختلفة.
إليك كيفية القيام بذلك: استخدم django-modeltranslation لإضافة حقول قابلة للترجمة إلى نماذجك، ثم قم بأتمتة الترجمة بالذكاء الاصطناعي باستخدام TranslateBot.
حزم ترجمة قاعدة بيانات Django
تحل عدة حزم خارجية مشكلة ترجمة قاعدة البيانات، كل منها بهندسة معمارية مختلفة.
django-modeltranslation
يضيف أعمدة خاصة باللغة مباشرة إلى جداولك الحالية. حقل title يصبح title_en، title_de، title_fr، وهكذا. تبقى الاستعلامات سريعة لأن كل شيء في نفس الجدول. واجهة الإدارة تعرض جميع اللغات جنبًا إلى جنب.
- المزايا: لا حاجة لـ JOINs، استعلامات سريعة، وصول شفاف عبر واصفات الحقول، نظام بيئي ناضج
- العيوب: تغييرات في المخطط لكل لغة جديدة، جداول أعرض
django-parler
ينشئ جدول ترجمة منفصل لكل نموذج. يبقى الجدول الأصلي نظيفًا، وتُخزن الترجمات في جدول مرتبط عبر مفتاح خارجي.
- المزايا: مخطط نظيف، سهولة إضافة لغات دون ترحيل
- العيوب: يتطلب JOINs للمحتوى المترجم، أنماط استعلام أكثر تعقيدًا بعض الشيء
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 خطوة بخطوة
الخطوة 1: تثبيت الحزمة
TranslateBot يضم django-modeltranslation كاعتمادية اختيارية. قم بتثبيت كليهما مرة واحدة:
pip install translatebot-django[modeltranslation]
أو إذا كنت تستخدم uv:
uv add --dev translatebot-django[modeltranslation]
الخطوة 2: تكوين إعدادات 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 حتى يتمكن من تصحيح فئات الإدارة لإظهار حقول الترجمة.
الخطوة 3: تسجيل النماذج للترجمة
أنشئ ملف 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.
الخطوة 4: إنشاء وتشغيل الترحيلات
python manage.py makemigrations
python manage.py migrate
بعد ذلك، يحتوي جدول shop_product على أعمدة جديدة:
| العمود | النوع |
|---|---|
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 فارغ. إذا كان لديك 500 منتج مع 3 حقول قابلة للترجمة و3 لغات مستهدفة، فهذا 4,500 حقل فارغ ينتظر أن يُملأ.
ترجمة هذا المحتوى يدويًا ليست واقعية. حتى مع خدمة ترجمة محترفة، ستحتاج إلى تصدير البيانات وإرسالها والانتظار للتسليم واستيراد النتائج. بالنسبة لفريق صغير أو مطور منفرد، هذا عادة يعني أن الميزة لن تُطلق أبدًا.
هنا يأتي دور 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 للتحقق من الترجمات المفقودة تلقائيًا
- استكشف نماذج الذكاء الاصطناعي المدعومة للعثور على أفضل توازن بين الجودة والتكلفة لمشروعك