You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Wagtail Factories与Factory Boy测试页面路由失败求助

问题排查与解决办法

1. 测试站点冲突

WagtailPageTestCase会自动初始化一个默认测试站点和根页面,而你在setUpTestData中创建了独立的Site实例。assertPageIsRoutable默认使用TestCase自带的站点,导致无法找到自定义站点下的页面。

解决:
调用assertPageIsRoutable时显式指定你的自定义站点:

def test_category_route(self):
    for category in self.categories:
        self.assertPageIsRoutable(category, site=self.site)

2. 页面未设置为发布状态

Wagtail仅允许live=True的页面被路由访问,wagtail_factories的PageFactory默认不会自动设置页面为发布状态。

解决:
在页面工厂中添加live=True字段:

class BlogIndexPageFactory(wagtail_factories.PageFactory):
    title = "Blog Index"
    intro = "Welcome to the Blog"
    slug = "blog"
    live = True  # 新增发布状态设置

    class Meta:
        model = models.BlogIndexPage

class CategoryIndexPageFactory(wagtail_factories.PageFactory):
    title = factory.sequence(lambda n: f"Category {n}")
    intro = factory.sequence(lambda n: f"Welcome to Category {n}")
    live = True  # 新增发布状态设置

    class Meta:
        model = models.CategoryIndexPage

3. 站点结构与路由预期不匹配

你将BlogIndexPage设为站点root_page,意味着它的访问路径是/而非/blog/,但报错路径显示为http://localhost:81/blog/category-1/,两者矛盾——此时CategoryIndexPage的正确路径应为/category-1/。

如果实际站点中/blog/是博客首页,需调整结构:

  • 创建根页面(如HomePage)作为Site的root_page
  • 将BlogIndexPage作为HomePage的子页面(slug设为"blog")
  • 再将CategoryIndexPage作为BlogIndexPage的子页面

调整后的工厂与测试代码:

# 定义HomePage工厂(需确保项目中有HomePage模型)
class HomePageFactory(wagtail_factories.PageFactory):
    title = "Home"
    slug = "home"
    live = True

    class Meta:
        model = models.HomePage

# 修改Site工厂,自动添加BlogIndexPage作为子页面
class SiteFactoryDefault(wagtail_factories.SiteFactory):
    is_default_site = True
    root_page = factory.SubFactory(HomePageFactory)

    @factory.post_generation
    def add_blog_index(self, create, extracted, **kwargs):
        if not create:
            return
        BlogIndexPageFactory.create(parent=self.root_page, slug="blog")

# 测试代码中获取正确的BlogIndexPage作为父页面
class TestBlogIndex(WagtailPageTestCase):
    @classmethod
    def setUpTestData(cls):
        cls.site = SiteFactoryDefault.create()
        cls.index = models.BlogIndexPage.objects.get(parent=cls.site.root_page, slug="blog")
        cls.categories = CategoryIndexPageFactory.create_batch(4, parent=cls.index)

    def test_category_route(self):
        for category in self.categories:
            self.assertPageIsRoutable(category, site=self.site)

4. 显式指定CategoryIndexPage的slug

若Factory Boy自动生成的slug与路由预期不符(如特殊字符处理问题),可显式设置slug:

class CategoryIndexPageFactory(wagtail_factories.PageFactory):
    title = factory.sequence(lambda n: f"Category {n}")
    intro = factory.sequence(lambda n: f"Welcome to Category {n}")
    slug = factory.sequence(lambda n: f"category-{n}")  # 显式定义slug
    live = True

    class Meta:
        model = models.CategoryIndexPage

内容的提问来源于stack exchange,提问作者user3605767

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 14:25:43