跟随Wagtail教程添加标签时遭遇404页面未找到问题
问题:Wagtail博客点击标签出现404错误
按照Wagtail官方教程为快速入门博客添加标签后,点击添加的“foood”标签时出现Page not found (404)错误,请求路径/tags/?tag=foood无法匹配到对应页面。以下是相关代码:
相关代码
blog/models.py 中的 BlogTagIndexPage 类
# Add BlogTagIndexPage class BlogTagIndexPage(Page): def get_context(self, request): # Filter by tag tag = request.GET.get('tag') blogpages = BlogPage.objects.filter(tags__name=tag) # Update template context context = super().get_context(request) context['blogpages'] = blogpages return context
blog/templates/blog/blog_tag_index_page.html 模板
{% extends "base.html" %} {% load wagtailcore_tags %} {% block content %} {% if request.GET.tag %} <h4>Showing pages tagged "{{ request.GET.tag }}"</h4> {% endif %} {% for blogpage in blogpages %} <p> <strong><a href="{% pageurl blogpage %}">{{ blogpage.title }}</a></strong><br /> <small>Revised: {{ blogpage.latest_revision_created_at }}</small><br /> </p> {% empty %} No pages found with that tag. {% endfor %} {% endblock %}
完整的 models.py 代码
from django.db import models from django import forms from modelcluster.fields import ParentalKey, ParentalManyToManyField # add tags to allow users to view tagged content from modelcluster.contrib.taggit import ClusterTaggableManager from taggit.models import TaggedItemBase # add wagtail classes and methods from wagtail.models import Page, Orderable from wagtail.fields import RichTextField from wagtail.admin.panels import FieldPanel, InlinePanel, MultiFieldPanel from wagtail.search import index # add snippets from wagtail.snippets.models import register_snippet # Add BlogTagIndexPage class BlogTagIndexPage(Page): def get_context(self, request): # Filter by tag tag = request.GET.get('tag') blogpages = BlogPage.objects.filter(tags__name=tag) # Update template context context = super().get_context(request) context['blogpages'] = blogpages return context class BlogIndexPage(Page): intro = RichTextField(blank=True) content_panels = Page.content_panels + [ FieldPanel('intro') ] # add the get_context method: def get_context(self, request): # Update context to include only published posts, ordered by reverse-chron context = super().get_context(request) blogpages = self.get_children().live().order_by('-first_published_at') context['blogpages'] = blogpages return context class BlogPageTag(TaggedItemBase): content_object = ParentalKey( 'BlogPage', related_name='tagged_items', on_delete=models.CASCADE ) class BlogPage(Page): date = models.DateField("Post date") intro = models.CharField(max_length=250) body = RichTextField(blank=True) # the main_image method: def main_image(self): gallery_item = self.gallery_images.first() if gallery_item: return gallery_item.image else: return None search_fields = Page.search_fields + [ index.SearchField('intro'), index.SearchField('body'), ] # Add authors: authors = ParentalManyToManyField('blog.Author', blank=True) # Add tags: tags = ClusterTaggableManager(through=BlogPageTag, blank=True) content_panels = Page.content_panels + [ # Add MultiFieldPanel including date panel, authors panel MultiFieldPanel([ FieldPanel('date'), FieldPanel('authors', widget=forms.CheckboxSelectMultiple), # Add field for tags: FieldPanel('tags'), ], heading="Blog information"), FieldPanel('intro'), FieldPanel('body'), InlinePanel('gallery_images', label="Gallery images"), ] class BlogPageGalleryImage(Orderable): page = ParentalKey(BlogPage, on_delete=models.CASCADE, related_name='gallery_images') image = models.ForeignKey( 'wagtailimages.Image', on_delete=models.CASCADE, related_name='+' ) caption = models.CharField(blank=True, max_length=250) panels = [ FieldPanel('image'), FieldPanel('caption'), ] @register_snippet class Author(models.Model): name = models.CharField(max_length=255) author_image = models.ForeignKey( 'wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+' ) panels = [ FieldPanel('name'), FieldPanel('author_image'), ] def __str__(self): return self.name class Meta: verbose_name_plural = 'Authors'
blog_page.html 模板
{% extends "base.html" %} {% load wagtailcore_tags wagtailimages_tags %} {% block body_class %}template-blogpage{% endblock %} {% block content %} <h1>{{ page.title }}</h1> <p class="meta">{{ page.date }}</p> <!-- Add authors multi-field panel to blog page template: --> {% with authors=page.authors.all %} {% if authors %} <h3>Posted by:</h3> <ul> {% for author in authors %} <li style="display: inline"> {% image author.author_image fill-40x60 style="vertical-align: middle" %} {{ author.name }} </li> {% endfor %} </ul> {% endif %} {% endwith %} <div class="intro">{{ page.intro }}</div> {{ page.body|richtext }} <!-- image gallery --> {% for item in page.gallery_images.all %} <div style="float: inline-start; margin: 10px"> {% image item.image fill-320x240 %} <p>{{ item.caption }}</p> </div> {% endfor %} <p><a href="{{ page.get_parent.url }}">Return to blog</a></p> <!-- Add this: --> {% with tags=page.tags.all %} {% if tags %} <div class="tags"> <h3>Tags</h3> {% for tag in tags %} <a href="{% slugurl 'tags' %}?tag={{ tag }}"><button type="button">{{ tag }}</button></a> {% endfor %} </div> {% endif %} {% endwith %} {% endblock %}
原因与解决方案
你遗漏了两个核心步骤:
1. 在Wagtail后台创建BlogTagIndexPage实例
BlogTagIndexPage只是页面模型,必须在后台实际创建该页面才能被访问:
- 登录Wagtail管理后台
- 找到你的博客索引页面(
BlogIndexPage),点击添加子页面 - 选择Blog Tag Index Page类型,标题可自定义(比如“标签归档”),但slug必须设置为
tags(和模板中{% slugurl 'tags' %}的slug一致) - 保存并发布该页面
2. 确认项目URL路由配置正确
检查项目根目录的urls.py,确保已正确引入Wagtail的页面路由:
from wagtail import urls as wagtail_urls from wagtail.admin import urls as wagtailadmin_urls from wagtail.documents import urls as wagtaildocs_urls urlpatterns = [ path('admin/', include(wagtailadmin_urls)), path('documents/', include(wagtaildocs_urls)), # 其他自定义路由... path('', include(wagtail_urls)), ]
这个配置让Wagtail处理所有页面的路由匹配,包括你创建的tags页面。
额外检查点
- 确认创建的
BlogTagIndexPage已发布,未发布页面无法通过前端访问 - 核对模板中
{% slugurl 'tags' %}生成的URL,必须和后台创建页面的slug完全匹配
内容的提问来源于stack exchange,提问作者siralbert
相关产品推荐
相关产品推荐

