我正在使用Django CMS与Django Parler并遇到一个让我发疯的问题,所以如果有人可以提供帮助,我将非常感激!
所以我正在创建一个简单的博客应用程序,将slug作为可翻译字段。这是简化的模型:
from parler.models import TranslatableModel, TranslatedFields
class Article(TranslatableModel):
...
translations = TranslatedFields(
...
slug = models.SlugField(_('slug'), max_length=255, blank=True, allow_unicode=True),
meta = {'unique_together': (('language_code', 'slug'),)}
)
...
def get_absolute_url(self):
return reverse('blog:article_detail', kwargs={'slug': self.slug})
以下是网址:
from django.conf.urls import include, url
from .views import ArticleDetailView
urlpatterns = [
...
url(r'^(?P<slug>\w[-\w]*)/$', ArticleDetailView.as_view(), name='article_detail'),
]
最后这里是观点:
from django.views.generic import DetailView
from parler.views import TranslatableSlugMixin
from .models import Article
class ArticleDetailView(TranslatableSlugMixin, DetailView):
model = Article
template_name = 'blog/_article.html'
我创建了一篇英文,法文和英文的文章。德语,每种语言都有不同的slug,可以打电话给那些:
/en/blog/english-slug
/fr/blog/french-slug
/de/blog/german-slug
我可以正确导航到这些,但在Django CMS中,您可以在顶部的语言菜单中显示链接:
/en/blog/english-slug
/fr/blog/english-slug
/de/blog/english-slug
这没关系,因为这是视图中的TranslatableSlugMixin处理的内容(请参阅此处http://django-parler.readthedocs.io/en/latest/api/parler.views.html)。
因此,当我点击其中一个链接(比如法语链接)时,视图会正确找到正确的文章并将我重定向到正确的网址。所以点击:
/fr/blog/english-slug
我已正确地接受了:
/fr/blog/french-slug
但是这里一切都出错了。我现在想要导航回英文页面,显示为:
/en/blog/french-slug
但是当我点击链接时,它会导航到404.如果我从法语网址导航到德语网址,这是相同的。但是,如果我马上从英语到德语,它就会起作用。
很抱歉,我知道这很难解释,但似乎翻译的工作方式是从base / default到其他语言,但在语言之间交换或返回base / default时无法正常工作。
肯定TranslatableSlugMixin旨在允许这种情况发生?!我在这里错过了一些东西吗?
非常感谢任何帮助。很高兴在必要时提供更多信息。
由于
答案 0 :(得分:1)
好的,所以我已经弄清楚如何完成这项工作,事实证明这是事情的组合...
使用默认的Django CMS选择器是错误的:
{% language_chooser "menu/language_chooser.html" %}
这会导致我上面描述的网址:
/en/blog/english-slug
/fr/blog/english-slug
/de/blog/english-slug
阅读Django Parler文档让我使用他们的语言导航菜单:
{% for lang_code, title in LANGUAGES %}
{% get_language_info for lang_code as lang %}
{% get_translated_url lang_code as tr_url %}
{% if tr_url %}<li{% if lang_code == LANGUAGE_CODE %} class="is-selected"{% endif %}><a href="{{ tr_url }}" hreflang="{{ lang_code }}">{{ lang.name_local|capfirst }}</a></li>{% endif %}
{% endfor %}
这会导致网址指向正确的位置:
/en/blog/english-slug
/fr/blog/french-slug
/de/blog/german-slug
为了让Django Parler导航工作,我需要更新模型中的get_absolute_url()来处理不同的语言。我这样做了如下:
from django.utils.translation import get_language
from parler.models import TranslatableModel, TranslatedFields
class Article(TranslatableModel):
...
def get_absolute_url(self):
language = get_language()
if self.has_translation(language):
slug = self.safe_translation_getter('slug', language_code=language)
return reverse('blog:article_detail', kwargs={'slug': slug})
# no translation so fallback to all article list
return reverse('blog:article_list')
唷!那真让我头疼!希望这对未来的其他人有所帮助!
P.S。在我的研究期间,我遇到了这个看起来非常棒的博客应用程序:
https://github.com/nephila/djangocms-blog
这帮助我走到了这场噩梦的最底层!
查看djangocms-blog中的get_absolute_url()(上面的链接),他们有一个更好的解决方案。他们的实施是:
from django.utils.translation import get_language
from parler.models import TranslatableModel, TranslatedFields
class Article(TranslatableModel):
...
def get_absolute_url(self, lang=None):
if not lang or lang not in self.get_available_languages():
lang = self.get_current_language()
if not lang or lang not in self.get_available_languages():
lang = get_language()
with switch_language(self, lang):
slug = self.safe_translation_getter('slug', language_code=lang, any_language=True)
return reverse('blog:article_detail', kwargs={'slug': slug})
感谢nephila,这让我免受了许多诅咒和挫折:)