wagtail-factories中PageChooserBlock失效,Navigation工厂top_bar字段创建失败
问题分析
核心问题是URLChoiceStreamFactory未正确生成符合Wagtail StreamBlock要求的数据结构,同时存在几处工厂配置细节错误:
- StreamBlockFactory的使用未匹配内部结构
- PageChooserBlock关联的页面实例未确保正确保存
- 直接使用
faker.word()会生成固定值,而非动态随机内容 - ListBlockFactory未明确生成条目数量
修复后的Factory代码
from home.models import Navigation, TopBar, LinkBlock, URLChoiceStream, HomePage import factory import wagtail_factories from faker import Faker faker = Faker() class HomePageFactory(wagtail_factories.PageFactory): class Meta: model = HomePage class URLChoiceStreamFactory(wagtail_factories.StreamBlockFactory): class Meta: model = URLChoiceStream @factory.lazy_attribute def internal(self): # 确保页面实例先保存再关联 page = HomePageFactory.create() return wagtail_factories.PageChooserBlockFactory(page=page).build() class LinkBlockFactory(wagtail_factories.StructBlockFactory): name = factory.Faker("sentence", nb_words=2, variable_nb_words=False) url = factory.SubFactory(URLChoiceStreamFactory) class Meta: model = LinkBlock class TopBarFactory(wagtail_factories.StructBlockFactory): # 改用factory.Faker动态生成标题 title = factory.Faker("word") # 明确ListBlock生成的条目数量 top_bar_links = wagtail_factories.ListBlockFactory(LinkBlockFactory, count=2) class Meta: model = TopBar class NavFactory(factory.django.DjangoModelFactory): name = factory.Faker("name") top_bar = wagtail_factories.StreamFieldFactory( { "top_bar": factory.SubFactory(TopBarFactory), }, # 匹配模型max_num=1的配置 factory_kwargs={"count": 1} ) class Meta: model = Navigation
关键修复点说明
URLChoiceStreamFactory修正
- 用
factory.lazy_attribute延迟生成Page实例,确保页面保存后再关联到PageChooserBlock - 调用
PageChooserBlockFactory.build()生成符合要求的块数据结构
- 用
TopBarFactory修正
- 将
title = faker.word()改为title = factory.Faker("word"),每次创建实例时生成新的随机标题 - 给
ListBlockFactory添加count=2参数,明确生成的链接数量,避免空值问题
- 将
NavFactory修正
- 给
StreamFieldFactory添加factory_kwargs={"count": 1},确保生成一个有效的TopBar条目,匹配模型配置
- 给
测试验证
运行以下代码验证工厂功能:
# 创建Navigation实例 nav = NavFactory.create() # 检查top_bar字段数据 print(nav.top_bar) # 验证内部链接关联的HomePage实例 print(nav.top_bar[0].value['top_bar_links'][0]['url'][0].value)
内容的提问来源于stack exchange,提问作者Mamed
相关产品推荐
相关产品推荐

