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 в обратной функции.
Возможно, лучшим выбором будет написать промежуточное ПО, а не пользовательский тег.
Во всяком случае, пока это работает, но я приветствую, если у кого-то есть или найдет более приятное и общее решение для этого.
Кажется очень странным, что не существует готового решения этой проблемы.
Но, возможно, я ошибаюсь и просто не могу найти это.