Django: Как правильно установить и изменить языки, которые отражают URL?

settings.py:
INSTALLED_APPS = [
    ...,
    'modeltranslation',
]
TIME_ZONE = 'Europe/Belgrade'
USE_I18N = True
USE_L10N = True
USE_TZ = True
LANGUAGES = (
    ('en-us', _('English')),
    ('hu', _('Hungarian')),
    ('sr-latn', _('Serbian')),
)
LOCALE_PATHS = (
    os.path.join(BASE_DIR, 'locale'),
    os.path.join(BASE_DIR, 'books', 'locale'),
)

urls.py:
urlpatterns = [
    url(r'^i18n/', include('django.conf.urls.i18n')),
    ]
urlpatterns += i18n_patterns(
    url(_r('^books/'), include('books.urls', namespace='books'))
    )

Мой язык по умолчанию английский. Моя модель имеет 3 поля заголовка для каждого языка. Как работает пакет modeltranslation, то есть:

(title_en, title_hu, title_sr_latn)

Так как я использую поле slug для представления url экземпляра модели в url, у меня есть 3 поля slug для каждого языка соответственно в моем классе модели.

Я не вижу никакого смысла в том, что мой URL должен выглядеть примерно так на венгерском языке, например:

127.0.0.1/hu/konyvek/learn-django

Я хочу, чтобы мои URL выглядели так:

Английский URL (я не хочу иметь языковой префикс для языка по умолчанию!):

127.0.0.1/books/the-lord-of-the-rings

Венгерский URL:

127.0.0.1/hu/konyvek/a-gyuruk-ura

Сербский URL (к сожалению, приставка сербского языка выглядит ужасно уродливо, но это уже другая тема):

127.0.0.1/sr-latn/knjige/gospodar-prstenova

Я пока не смог найти ничего, что решило бы эту проблему. Очевидно, что я не могу использовать ни один из них при переключении значения следующего элемента формы в шаблоне: {{ request.path }} или же {{ request.get_absolute_path|slice:'3:' }}

Поэтому я временно исключил следующий элемент. Когда я переключаю языки, на моей главной странице все работает хорошо. If I go to a books page for example (/hu/konyvek/), it shows the language properly but if I want from there to change to a different language it doesn't let me do it. It just reloads the current page.

Any suggestion how to accomplish this?

1 ответ

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

Я нашел этот код по адресу https://djangosnippets.org/snippets/2875/

@register.simple_tag(takes_context=True)
def change_lang(context, lang=None, *args, **kwargs):
    path = context['request'].path
    url_parts = resolve( path )

    cur_language = get_language()

    try:
        activate(lang)
        url = reverse( url_parts.view_name, kwargs=url_parts.kwargs )
    finally:
        activate(cur_language)


    return "%s" % url

Но это решение решило только половину моей проблемы. Он правильно принял перевод части книги "url", но часть слизняка "the the lord-of-the-rings /" осталась старой. Django не смог разрешить путь URL-адреса, потому что язык был переключен, первый уровень URL-адреса изменился, но в urlconf такого нет, например, ei 'konyvek / the-lord-of-rings /'.

Я немного изменил код:

@register.simple_tag(takes_context=True)
def change_lang(context, lang=None, *args, **kwargs):

    path = context['request'].path
    url_parts = resolve(path)

    cur_language = get_language()

    try:
        translation.activate(lang)
        if 'book' in context:
            slug = context['book'].slug
            url = reverse(url_parts.view_name, kwargs={'slug': slug})
        else:
            url = reverse(url_parts.view_name, kwargs=url_parts.kwargs)
    finally:
        translation.activate(cur_language)

    return '%s' % url

"К счастью", в контекстном списке есть экземпляр объекта, называемый "book", поэтому я мог использовать его, чтобы выбрать соответствующее поле слагов после того, как я активировал новый язык, а затем перенаправил его в kwargs в обратной функции.

Возможно, лучшим выбором будет написать промежуточное ПО, а не пользовательский тег.

Во всяком случае, пока это работает, но я приветствую, если у кого-то есть или найдет более приятное и общее решение для этого.

Кажется очень странным, что не существует готового решения этой проблемы.

Но, возможно, я ошибаюсь и просто не могу найти это.

Другие вопросы по тегам