← Назад к вопросам

Как реализовывается мультиязычность в Django?

2.2 Middle🔥 71 комментариев
#Django

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Мультиязычность в Django

Django имеет встроенную систему интернационализации (i18n) для поддержки множества языков. Это мощный инструмент, но требует правильной настройки и понимания концепций.

Настройка Django для мультиязычности

# settings.py

LANGUAGE_CODE = "en-us"

LANGUAGES = [
    ("en", "English"),
    ("ru", "Russian"),
    ("de", "German"),
    ("fr", "French"),
]

LOCALE_PATHS = [
    BASE_DIR / "locale",  # Путь где хранятся переводы
]

INSTALLED_APPS = [
    "django.contrib.auth",
    "django.contrib.contenttypes",
    # ...
]

MIDDLEWARE = [
    "django.middleware.locale.LocaleMiddleware",  # ВАЖНО: после SessionMiddleware
    # ...
]

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [],
        "APP_DIRS": True,
        "OPTIONS": {
            "context_processors": [
                "django.template.context_processors.i18n",
            ],
        },
    },
]

USE_I18N = True
USE_L10N = True

Метод 1: Перевод строк в Python коде

from django.utils.translation import gettext, gettext_lazy
from django.utils.translation import ngettext, gettext as _

# Простой перевод
message = _("Hello, World!")  # Будет переведено

# Ленивый перевод (для использования на уровне модели/view)
error_message = gettext_lazy("Something went wrong")

# Множественные формы
from django.utils.translation import ngettext

def display_count(count):
    message = ngettext(
        "You have %(count)d item",
        "You have %(count)d items",
        count
    ) % {"count": count}
    return message

print(display_count(1))  # You have 1 item
print(display_count(5))  # You have 5 items

Метод 2: Перевод в шаблонах

{% load i18n %}

<!-- Простой перевод -->
<h1>{% trans "Welcome" %}</h1>

<!-- Перевод с переменными -->
<p>{% blocktrans %}Hello, {{ name }}!{% endblocktrans %}</p>

<!-- Множественные формы -->
{% blocktrans count counter=items|length %}
You have {{ counter }} item
{% plural %}
You have {{ counter }} items
{% endblocktrans %}

<!-- Переключение языка -->
{% for lang in LANGUAGES %}
    <a href="/{{ lang.0 }}/">{{ lang.1 }}</a>
{% endfor %}

Метод 3: Переводы в моделях

from django.db import models
from django.utils.translation import gettext_lazy as _

class Product(models.Model):
    # gettext_lazy — для того, чтобы перевод происходил при отображении
    name = models.CharField(
        max_length=100,
        help_text=_("Product name")
    )
    description = models.TextField(
        help_text=_("Product description")
    )
    created_at = models.DateTimeField(auto_now_add=True)
    
    class Meta:
        verbose_name = _("Product")
        verbose_name_plural = _("Products")
    
    def __str__(self):
        return self.name

Метод 4: Перевод сообщений об ошибках

from django import forms
from django.utils.translation import gettext_lazy as _

class ContactForm(forms.Form):
    name = forms.CharField(
        label=_("Name"),
        error_messages={
            "required": _("Name is required"),
            "max_length": _("Name is too long"),
        }
    )
    email = forms.EmailField(
        label=_("Email address"),
        error_messages={
            "required": _("Email is required"),
            "invalid": _("Invalid email address"),
        }
    )
    message = forms.CharField(
        label=_("Message"),
        widget=forms.Textarea,
        error_messages={
            "required": _("Message is required"),
        }
    )

def contact_form_view(request):
    if request.method == "POST":
        form = ContactForm(request.POST)
        if form.is_valid():
            # Обработка
            messages.success(request, _("Message sent successfully"))
        else:
            messages.error(request, _("Please fix the errors below"))
    else:
        form = ContactForm()
    
    return render(request, "contact.html", {"form": form})

Создание файлов переводов

# Шаг 1: Создать базовый .po файл
python manage.py makemessages -l ru
# Создаст: locale/ru/LC_MESSAGES/django.po

# Шаг 2: Отредактировать django.po
# msgid — оригинальный текст
# msgstr — переведённый текст

# Шаг 3: Скомпилировать переводы
python manage.py compilemessages
# Создаст: locale/ru/LC_MESSAGES/django.mo

# Для нескольких языков
python manage.py makemessages -l ru -l de -l fr

Пример файла перевода (locale/ru/LC_MESSAGES/django.po):

msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Language: ru\n"

msgid "Hello, World!"
msgstr "Привет, мир!"

msgid "You have %(count)d item"
msgid_plural "You have %(count)d items"
msgstr[0] "У вас %(count)d товар"
msgstr[1] "У вас %(count)d товара"
msgstr[2] "У вас %(count)d товаров"

Переключение языка

from django.views.i18n import set_language
from django.shortcuts import redirect
from django.utils.translation import activate

# Способ 1: Через встроенное представление Django
urlpatterns = [
    path("i18n/", include("django.conf.urls.i18n")),
]

# Способ 2: Кастомное представление
def change_language(request, language):
    activate(language)  # Активировать язык
    response = redirect(request.META.get("HTTP_REFERER", "/"))
    response.set_cookie("django_language", language)  # Сохранить в cookie
    return response

# Способ 3: Определить по URL
# urls.py
urlpatterns = [
    path("en/", include("myapp.urls")),
    path("ru/", include("myapp.urls")),
]

# middleware.py
class LanguageMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
    
    def __call__(self, request):
        lang = request.path.split("/")[1]  # en или ru
        if lang in ["en", "ru"]:
            activate(lang)
        
        response = self.get_response(request)
        return response

API для мультиязычности

from rest_framework import viewsets, serializers
from django.utils.translation import activate, get_language

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = ["id", "name", "description"]

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    
    def get_serializer_context(self):
        context = super().get_serializer_context()
        # Активировать язык из параметра запроса
        lang = self.request.query_params.get("lang", "en")
        activate(lang)
        context["language"] = lang
        return context

# Использование
# GET /api/products/?lang=ru
# GET /api/products/?lang=en

Хранение переводов в БД (для динамических данных)

from django.db import models
from parler.models import TranslatableModel, TranslatedFields

class Article(TranslatableModel):
    # Используется пакет django-parler
    translations = TranslatedFields(
        title=models.CharField(max_length=200),
        content=models.TextField(),
    )
    
    created_at = models.DateTimeField(auto_now_add=True)
    
    def __str__(self):
        return self.title

# Использование
article = Article.objects.language("ru").get(id=1)
print(article.title)  # На русском

article.translate("en")
print(article.title)  # На английском

Юнит-тесты для переводов

from django.test import TestCase, override_settings
from django.utils.translation import activate, gettext as _

class TranslationTestCase(TestCase):
    
    @override_settings(LANGUAGE_CODE="en")
    def test_english_translation(self):
        activate("en")
        # Важно: убедись, что .mo файл скомпилирован
        self.assertEqual(_("Hello"), "Hello")
    
    @override_settings(LANGUAGE_CODE="ru")
    def test_russian_translation(self):
        activate("ru")
        self.assertEqual(_("Hello"), "Привет")
    
    def test_language_switching(self):
        activate("en")
        en_text = _("Welcome")
        
        activate("ru")
        ru_text = _("Welcome")
        
        self.assertNotEqual(en_text, ru_text)

Best Practices

  1. Используй gettext_lazy для моделей и форм — переводится при отображении
  2. Используй gettext для коммуникаций — письма, логи
  3. Всегда компилируй переводыmakemessages и compilemessages
  4. Структурируй переводы — не смешивай языки в одном файле
  5. Тестируй переводы — проверяй все языки
  6. Используй django-parler для контента в БД — для пользовательского контента
  7. Форматируй даты по локали — используй date filter в шаблонах
  8. Документируй ключи переводов — что означает каждый ключ

Мультиязычность требует внимания к деталям, но Django предоставляет все инструменты для реализации.

Как реализовывается мультиязычность в Django? | PrepBro