Возможно ли перевести пути (i18n, gettext_lazy) в RoutablePageMixin-Pages?
Я создал страницу с помощью RoutablePageMixin и определил дочерний путь. Я хочу перевести этот дочерний путь на основе активного языка с помощью gettext_lazy, как это работает в Django в рамках urlpatterns. Я всегда получаю 404. Возможно ли это вообще или я что-то упускаю?
Вот мое определение страницы:
class StudyBrowserPage(RoutablePageMixin, TranslatedPage):
page_description = "Weiterleitung zum Studienbrowser"
@path('')
def list_studies(self, request):
studies = Study.objects.all()
return self.render(request, context_overrides={
'studies': studies
})
# here I actually want another parameter, but i tried to keep it simple. So don't mind the uselessness of the function.
@path(_('studie') + '/')
def study_detail_view(self, request):
return self.render(request, template='wagtail_home/study_detail.html')
Я перевел строку в моем файле django.po:
msgid "studie"
msgstr "study"
Вызов .../studie/
работает. .../study/
не работает.
Редактирование: Я думаю, что у меня есть все необходимые настройки в моем конфиге:
"context_processors": 'django.template.context_processors.i18n',
USE_I18N = True WAGTAIL_I18N_ENABLED = True
У меня также установлен wagtail-localize.
Вполне возможно, что _('studie')
все еще является прокси и не преобразуется в ленивую строку при интерпретации, или что английская локаль не активирована при использовании /study/
.
Если это первое, то попробуйте присвоить путь переменной, а затем форсировать его:
from django.utils.encoding import force_str
from django.utils.translation import gettext_lazy as _
STUDY_PATH = _('studie')
class StudyBrowserPage(RoutablePageMixin, TranslatedPage):
....
@path(force_str(STUDY_PATH) + '/')
def study_detail_view(self, request):
return self.render(request, template='wagtail_home/study_detail.html')
Хотя, наверное, проще просто объявить несколько путей:
@path('studie/')
@path('study/')
def study_detail_view(self, request):
return self.render(request, template='wagtail_home/study_detail.html')
Если вы хотите, чтобы путь был переменной, а не строковым литералом, то вам просто нужно искать совпадение с этой переменной и перевести результат.
Это страница продукта, показывающая список экземпляров модели Django (Product
). Каждый из них имеет атрибут sku
, который может быть уникальным для каждой локали, или уникальным для продукта и общим для всех локалей.
Путь sku
показывает подробную информацию о данном продукте. Метод product_detail
сначала ищет соответствие в текущей локали и использует его, если оно найдено. Если совпадение не найдено в текущей локали, но найдено в другой, метод пытается найти переведенный экземпляр и использует его, если он найден. Если совпадения нет или перевод для текущей локали отсутствует, то возвращается страница листинга:
class ProductPage(TranslatablePageMixin, RoutablePageMixin, Page):
parent_page_types = ["home.HomePage"]
subpage_types = []
max_count = 1
intro = RichTextField()
content_panels = Page.content_panels + [
FieldPanel('intro')
]
@path("")
def product_list(self, request):
products = Product.objects.filter(locale_id=Locale.get_active().id, live=True)
return self.render(
request,
context_overrides={
"products": products,
},
template="product/product_list.html",
)
@path("<str:sku>/")
def product_detail(self, request, sku):
active_locale = Locale.get_active()
# only show live products
products = Product.objects.filter(sku=sku, live=True)
if products and products.filter(locale_id=active_locale.id):
# if live product in active locale
return self.render(
request,
context_overrides={
"product": products.first().localized,
},
template="product/product_detail.html",
)
else:
# live product not in active locale
if products:
# product matching sku and live in other locales, try to find product in current locale
# redirect request to product if found and if live else send request to product list instead
translated = products.first().get_translation_or_none(active_locale)
return HttpResponseRedirect(self.url + (translated.sku if (translated and translated.live) else ''))
# no live products matching that sku in this locale, redirect to product list instead
return HttpResponseRedirect(self.url)