Если вы работали со встроенным фреймворком интернационализации (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 пошагово
Шаг 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-интеграцию для автоматической проверки отсутствующих переводов
- Изучите поддерживаемые ИИ-модели, чтобы найти лучший баланс качества и стоимости для вашего проекта