Pull to refresh

Многоязычные модели Django для начинающих

Django *

Вводная


Работаю я, как и все адекватные программисты, над социальным порталом который покорит всех от грудничков до маразматиков. И так как цели наполеоновские — нужно учесть возможность использования сервиса даже теми представителями человечества, которые не владеют великим и могучим. Знаю, что многие долго боролись с вопросом локализации именно контента (перевод отдельных полей модели на разные языки), т.к. локализация интерфейса, в пределах общепринятых, в Django решена. Суть проблемы в том, чтобы одна и та же модель (это важно! к примеру пункты единого для всех языков каталога) имела переводы своих полей на разные языки. Те кто давно «на игле» этого фреймворка уже наверняка нашли для себя наиболее подходящую методу решения этой проблемы, я же хочу предложить способ решения и набросать порядок действий для начинающих, чтобы они не сбежали по рельсам на рубиновые копи.

Отмазка


Совсем недавно мне подвернулся счастливый случай начать превращение из личинки-PHP'шника в жука-Python'оида. Так что сразу ногами не бейте. Эта заметка (не статья) представляет из себя HowTo для таких же начинающих.

Используемые материалы


Для локализации моделей мы будем использовать приложение для Django — django-modeltranslation. Я выбрал именно его среди прочих по следующим причинам:
  • работает с Django 1.3
  • добавляет переводимые поля для языков в ту же таблицу, т.е. не будет лишних JOIN'ов
  • не требует внесения никакого кода в уже существующие модели
  • почти безболезненно включается и отключается
  • в админке локализованная модель интегрируется с другими модулями (меня волновал mptt)

Ещё понадобится South — установленный и работающий.
Собственно всё (не считая рабочего/разрабатываемого сайта на django).

HowTo


Устанавливаем modeltranslation командой pip install django-modeltranslation.

Или качаем последнюю версию django-modeltranslation. Распаковываем, заходим в распакованный каталог и устанавливаем python setup.py install. Можно сразу из распакованного каталога руками закинуть в папку для статических файлов директорию modeltranslation/static/modeltranslation.

Далее работаем уже с нашим проектом

Добавляем 'modeltranslation' в INSTALLED_APPS файла настроек settings.py.

В тот же файл добавляем описание необходимых локализаций, язык по-умолчанию и импортируемый файл регистрации локализуемых моделей. В последнем MYPROJECT — нужно заменить на имя вашего проекта (оно же имя папки в которой он размещается), а translation — на имя самого .py файла без расширения, по умолчанию это translation.py. Этот файл один на весь проект и кладётся, соответственно, в корень проекта.

LANGUAGES = (
    ('ru', 'Russian'),
    ('en', 'English'),
)

MODELTRANSLATION_DEFAULT_LANGUAGE = 'ru'
MODELTRANSLATION_TRANSLATION_REGISTRY = 'MYPROJECT.translation'


В этом самом файле нам нужно создать классы содержащие указание какие поля (здесь это 'name' и 'description') нужно переводить и привязать эти классы к переводимым моделям (здесь это 'Modelka') Ваших приложений (здесь это 'app') сответствтенно:

# -*- coding: utf-8 -*-

from modeltranslation.translator import translator, TranslationOptions
from app.models import Modelka


class ModelkaTranslationOptions(TranslationOptions):
    """
    Класс настроек интернационализации полей модели Modelka.
    """
    
    fields = ('name', 'description',)

translator.register(Modelka, ModelkaTranslationOptions)


В этом месте можно сгенерировать миграцию python manage.py schemamigration app --auto.

South обнаружит новые поля для локализации и сгенерирует миграцию для их добавления. К слову если отключить приложение 'modeltranslation' — то также можно сгенерировать и миграцию для их удаления. Кроме того отдельное удобство в том, что modeltranslation привязывает язык по-умолчанию к оригинальным полям модели, т.е. это поле локализации и переводимое оригинальное поле модели будут идентичны.

Не забудьте потом применить миграцию: python manage.py migrate app.

И, наконец, настраиваем админку.

Очень важно чтобы админка описывалась в отдельном файле admin.py для каждого приложения!!! А не в файле моделей, как, признаюсь честно, по-началу пытался сделать я.

Для образца сразу приведу пример использования локализованной админки с админкой mptt:

# -*- coding: utf-8 -*-

from django.contrib import admin
from mptt.admin import MPTTModelAdmin
from modeltranslation.admin import TranslationAdmin
from models import Modelka

class ModelkaAdmin(MPTTModelAdmin, TranslationAdmin):
    """
    Настройка админки для Modelka.
    """
    
    list_display = ('name',)

    class Media:
        js = (
            '/static/modeltranslation/js/force_jquery.js',
            'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.min.js',
            '/static/modeltranslation/js/tabbed_translation_fields.js',
        )
        css = {
            'screen': ('/static/modeltranslation/css/tabbed_translation_fields.css',),
        }

    fieldsets = [
        (None, {
            'fields': [
                'name',
                'slug',
                'type',
                'description',
                'parent',
            ]
        }),
        (u'Лог', {
            'fields': [
                'author',
                'editor',
            ],
            'classes': ['collapse']
        })
    ]


admin.site.register(Modelka, ModelkaAdmin)


Обращаю Ваше внимание, что в примере сразу же включены скрипты для отображения переводов на разных вкладках. Это как раз те файлы которые я в начале предлагал скопировать в каталог для статического контента. Если Вы установили modeltranslation через pip — не забудьте собрать статические фалы командой python manage.py collectstatic (подробнее о статических файлах). Соответсвенно не забудьте подправить пути во вложенном Meta классе, если они у Вас отличаются.



На скриншоте видны вкладки языков для переводимых полей модели (скриншот с разрабатываемого приложения, потому языков больше чем в примере)

Работа с локализованной моделью

Собственно сама работа абсолютно прозрачна и также не затрагивает уже существующий код (наилучший язык отображения сайта может определяться как самим фреймворком, так и сторонними модулями, но это отдельная тема), если не понадобится где-то руками объявлять используемый язык через set_language. Т.е. модель будет возвращать значения полей на текущем языке приложения возвращаемом get_lang.
Tags:
Hubs:
Total votes 28: ↑26 and ↓2 +24
Views 18K
Comments Comments 28