Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 使用RoutablePageMixin基于slug的Wagtail自定义URL_Django_Wagtail - Fatal编程技术网

Django 使用RoutablePageMixin基于slug的Wagtail自定义URL

Django 使用RoutablePageMixin基于slug的Wagtail自定义URL,django,wagtail,Django,Wagtail,我想更改博客条目的URL以包含类别的slug(@route(r'^([category slug]/[post slug])-例如localost/health/health\u blog\u 1) 我将如何更改此模型 class PostPage(RoutablePageMixin, Page): body = RichTextField(blank=True) date = models.DateTimeField(verbose_name="Post date", defa

我想更改博客条目的URL以包含类别的slug(
@route(r'^([category slug]/[post slug]
)-例如localost/health/health\u blog\u 1)

我将如何更改此模型

class PostPage(RoutablePageMixin, Page):
    body = RichTextField(blank=True)
    date = models.DateTimeField(verbose_name="Post date", default=datetime.datetime.today)
    categories = ParentalManyToManyField('blog.BlogCategory', blank=True)
    tags = ClusterTaggableManager(through='blog.BlogPageTag', blank=True)

    content_panels = Page.content_panels + [
        FieldPanel('body', classname="full"),
        FieldPanel('categories', widget=forms.CheckboxSelectMultiple),
        FieldPanel('tags'),
    ]

    settings_panels = Page.settings_panels + [
        FieldPanel('date'),
    ]

    @property
    def blog_page(self):
        return self.get_parent().specific

    def get_context(self, request, *args, **kwargs):
        context = super(PostPage, self).get_context(request, *args, **kwargs)
        context['blog_page'] = self.blog_page
        return context

RoutablePageMixin
放在一边,Wagtail需要理解的是,你不应该像对待普通Django网站(或Rails或任何将路由映射到视图/控制器的框架)那样考虑URL。使用Wagtail时,页面路径是从页面树中构建的。因此,如果您希望类别显示在路径中,则它必须是树的一部分。在您的情况下,它应该是这样的:

HomePage (title: My Website, path: /)
|- CategoryPage (title: Health, path: /health/)
|  |- PostPage (title: Post 1, path: /health/post-1/)
|  |- PostPage (title: Post 2, path: /health/post-2/)
|  \- PostPage (title: Post 3, path: /health/post-3/)
\- CategoryPage (title: Diet, path: /diet/)
|- ...
\- ...
在这种情况下,您不需要进一步的破坏。这很简单,您可以免费获得类别页面,可以列出该类别中的所有帖子。显然,这种解决方案的缺点是,这样一来,一篇帖子只能属于一个类别

现在,让我们看看
RoutablePageMixin
s是如何工作的,以及它们可以提供什么。它们允许您创建虚拟页面(树中不存在的页面)。他们通过为路径添加后缀来实现这一点,例如,您在
/blog/
上有一个
bloginexpage
,但您还希望在
/blog/archives/
上提供年度存档,在
/blog/tags/
上提供标签过滤。您可以这样想(免责声明:这不是它实际的工作方式)当Wagtail接收到对
/blog/archives/
的请求时,此路径在树中不存在(也不存在
/blog/archives/
),但
/blog/
存在,因此Wagtail会加载可路由页面并检查与
/archives/
匹配的路由(因为它已经解析了
/blog/

因此,如果您想修改当前页面路径之前的内容,则
RoutablePageMixin
必须是树中父页面声明的一部分。假设您的
PostPage
是主页的直接子级,如下所示:

HomePage (title: My Website, path: /)
|- PostPage (title: Post 1, path: /health/post-1/)
|- PostPage (title: Post 2, path: /health/post-2/)
\- PostPage (title: Post 3, path: /health/post-3/)
然后,您将在
主页
的声明中包括
RoutablePageMixin

form django.shortcuts import get_object_or_404
from wagtail.contrib.routable_page.models import RoutablePageMixin, route
from wagtail.core.models import Page

class HomePage(RoutablePageMixin, Page):
    # Some fields

    @route(r'^(?P<category_slug>[\w-]+)/(?P<page_slug>[\w-]+)')
    def post_page(self, requets, category_slug, page_slug):
        post = get_object_or_404(PostPage, slug=page_slug, category_slug=category_slug)
        context = {
            'post': post
        }
        return render(request, 'posts/post_page.html', context)
尽管如此,我还是建议不要使用
重定向
。这实际上是在违背其核心原则

如果您确实更改了URL结构,使其与Wagtail的树路径不匹配,您还需要考虑更改站点地图URL。

class PostPage(Page):

    def serve(..):
        ....

    def get_sitemap_urls(self, request):
        """Overwrite the url."""
        return [
            {
                "location": '',  # Reverse subpage url
                "lastmod": (self.last_published_at or self.latest_revision_created_at),
            }
        ]
class PostPage(Page):

    def serve(..):
        ....

    def get_sitemap_urls(self, request):
        """Overwrite the url."""
        return [
            {
                "location": '',  # Reverse subpage url
                "lastmod": (self.last_published_at or self.latest_revision_created_at),
            }
        ]