Package: wagtail-factories
Factory boy classes for Wagtail CMSInstallationpipinstallwagtail-factoriesUsageDocumentation is still in progress, but see thetestsfor more examples.importwagtail_factoriesfrom.importmodelsclassMyCarouselItemFactory(wagtail_factories.StructBlockFactory):label='my-label'image=factory.SubFactory(wagtail_factories.ImageChooserBlockFactory)classMeta:model=models.MyBlockItemclassMyCarouselFactory(wagtail_factories.StructBlockFactory):title="Carousel title"items=wagtail_factories.ListBlockFactory(MyCarouselItemFactory)classMeta:model=models.MyCarouselclassMyNewsPageFactory(wagtail_factories.PageFactory):classMeta:model=models.MyNewsPageclassMyNewsPageChooserBlockFactory(wagtail_factories.PageChooserBlockFactory):page=factory.SubFactory(MyNewsPageFactory)classMyTestPageFactory(wagtail_factories.PageFactory):body=wagtail_factories.StreamFieldFactory({'carousel':factory.SubFactory(MyCarouselFactory),'news_page':factory.SubFactory(MyNewsPageChooserBlockFactory),})classMeta:model=models.MyTestPagedeftest_my_page():root_page=wagtail_factories.PageFactory(parent=None)my_page=MyTestPageFactory(parent=root_page,body__0__carousel__items__0__label='Slide 1',body__0__carousel__items__0__image__image__title='Image Slide 1',body__0__carousel__items__1__label='Slide 2',body__0__carousel__items__1__image__image__title='Image Slide 2',body__0__carousel__items__2__label='Slide 3',body__0__carousel__items__2__image__image__title='Image Slide 3',body__1__news_page__page__title="News",)Using StreamBlockFactoryStreamBlockFactorycan be used in conjunction with the other block factory types to create complex, nestedStreamValues, much like howStreamBlockcan be used to declare the blocks for a complexStreamField.First, define yourStreamBlockFactorysubclass, usingfactory.SubFactoryto wrap child block declarations. Be sure to include yourStreamBlocksubclass as the model attribute on the innerMetaclass.classMyStreamBlockFactory(wagtail_factories.StreamBlockFactory):my_struct_block=factory.SubFactory(MyStructBlockFactory)classMeta:model=MyStreamBlockThen include yourStreamBlockFactorysubclass on a model factory as the argument to aStreamFieldFactory.classMyPageFactory(wagtail_factories.PageFactory):body=wagtail_factories.StreamFieldFactory(MyStreamBlockFactory)classMeta:model=MyPageYou can then use a modified version of factory_boy’s deep object declaration syntax to build upStreamValueson the fly.MyPageFactory(body__0__my_struct_block__some_field="some value",body__0__my_struct_block__some_other_field="some other value",)To generate the default value for a block factory, terminate your declaration at the index and provide the block name as the value.MyPageFactory(body__0="my_struct_block")Alternative StreamFieldFactory declaration syntaxPrior to version 3.0,StreamFieldFactorycould only be used by providing a dict mapping block names to block factory classes as the single argument, for example:classMyTestPageWithStreamFieldFactory(wagtail_factories.PageFactory):body=wagtail_factories.StreamFieldFactory({"char_array":wagtail_factories.ListBlockFactory(wagtail_factories.CharBlockFactory),"int_array":wagtail_factories.ListBlockFactory(wagtail_factories.IntegerBlockFactory),"struct":MyBlockFactory,"image":wagtail_factories.ImageChooserBlockFactory,})classMeta:model=models.MyTestPageThis style of declaration is still supported, with the caveat that nested stream blocks are not supported for this approach. From version 3.0, allBlockFactoryvalues in aStreamFieldFactorydefinition of this stylemustbe wrapped in factory_boySubFactories. For example, the above example must be updated to the following for 3.0 compatibility.classMyTestPageWithStreamFieldFactory(wagtail_factories.PageFactory):body=wagtail_factories.StreamFieldFactory({"char_array":wagtail_factories.ListBlockFactory(wagtail_factories.CharBlockFactory),"int_array":wagtail_factories.ListBlockFactory(wagtail_factories.IntegerBlockFactory),"struct":factory.SubFactory(MyBlockFactory),"image":factory.SubFactory(wagtail_factories.ImageChooserBlockFactory),})classMeta:model=models.MyTestPageThis requirement doesnotapply toListBlockFactory, which is a subclass ofSubFactory.