Wagtail Factories
Wagtail Factories provides factory_boy classes tailored for generating Wagtail-specific objects like Pages, Images, Documents, and StreamFields, making it easier to create test data or seed development environments. The library is currently at version 4.4.0 and maintains an active release cadence, frequently updating to support new Wagtail versions.
Warnings
- breaking Wagtail Factories releases are tightly coupled to Wagtail versions. Upgrading `wagtail` often requires a corresponding upgrade of `wagtail-factories`. For example, v4.1.0 dropped support for Wagtail < 4.1, and v4.4.0 added support for Wagtail 7.
- breaking The usage of `StreamFieldFactory` was significantly changed in v3.0.0 with the introduction of `StreamBlockFactory`. Prior to this, `StreamFieldFactory` might have handled nested blocks implicitly, but now explicit block factories (e.g., `CharBlockFactory`, `ImageBlockFactory`) or `StreamFieldFactory._do_nothing` are often required for specific block types.
- breaking In v4.0.0, `ListBlockFactory` changed its return type for Wagtail versions >= 2.16 from a plain Python `list` to a `wagtail.blocks.list_block.ListValue`. This could affect existing code that expects a standard `list` object.
- breaking Dependency on `factory_boy` has evolved. `wagtail-factories` v2.0.1 required `factory_boy>=3.0`, and v2.1.0 further required `factory_boy>=3.2`. Using an older `factory_boy` version will lead to compatibility errors.
Install
-
pip install wagtail-factories
Imports
- PageFactory
from wagtail_factories import PageFactory
- StreamFieldFactory
from wagtail_factories import StreamFieldFactory
- CharBlockFactory
from wagtail_factories.blocks import CharBlockFactory
- ImageFactory
from wagtail_factories import ImageFactory
- ImageBlockFactory
from wagtail_factories.blocks import ImageBlockFactory
Quickstart
import factory
from django.db import models
from wagtail.models import Page
from wagtail.fields import RichTextField, StreamField
from wagtail import blocks
from wagtail_factories import PageFactory, StreamFieldFactory
from wagtail_factories.blocks import CharBlockFactory
# Define a simple Wagtail Page model
class MyPage(Page):
body = RichTextField(blank=True)
content = StreamField([
('heading', blocks.CharBlock(form_classname='full title')),
('paragraph', blocks.RichTextBlock()),
], use_json_field=True, blank=True)
content_panels = Page.content_panels # Simplified for example
# Define factories for the model and its StreamField blocks
class HeadingBlockFactory(CharBlockFactory):
class Meta:
model = blocks.CharBlock # For CharBlockFactory itself
class MyPageFactory(PageFactory):
class Meta:
model = MyPage
title = factory.Sequence(lambda n: f'Test Page {n}')
body = factory.Faker('text')
content = StreamFieldFactory({
'heading': HeadingBlockFactory,
'paragraph': StreamFieldFactory._do_nothing, # For simple blocks or when default behavior is fine
})
# Example usage (requires Django environment setup)
# To run this code, you'd typically need a Django project configured with Wagtail.
# For testing purposes, you might use Django's test client or a custom setup.
if __name__ == '__main__':
print("This quickstart demonstrates factory definition. To create instances, run within a configured Django/Wagtail project.")
print("Example: `page = MyPageFactory()` would create a page in your database.")
# Example of creating a page (would run within a Django test or shell):
# from django.test import TestCase
# class MyTest(TestCase):
# def test_page_creation(self):
# page = MyPageFactory()
# self.assertIsNotNone(page.pk)
# print(f"Created page: {page.title}")
# print(f"StreamField content keys: {[b.block_type for b in page.content]}")