# wagtail-factories

> Factory boy classes for wagtail

- **URL**: https://www.freshcrate.ai/projects/wagtail-factories
- **Author**: Michael van Tellingen
- **Category**: Frameworks
- **Latest version**: `v4.5.0` (2026-06-04)
- **License**: MIT
- **Source**: https://github.com/wagtail/wagtail-factories/
- **Language**: Python
- **GitHub**: 113 stars, 47 forks
- **Registry**: pypi (`wagtail-factories`)
- **Tags**: `pypi`

## Description

# wagtail-factories

Factory boy classes for Wagtail CMS

## Installation

``` shell
pip install wagtail-factories
```

## Usage

Documentation is still in progress, but see the
[tests](https://github.com/wagtail/wagtail-factories/tree/main/tests)
for more examples.

``` python
import wagtail_factories
from wagtail import models as wt_models

from . import models


class MyCarouselItemFactory(wagtail_factories.StructBlockFactory):
    label = 'my-label'
    image = factory.SubFactory(
        wagtail_factories.ImageChooserBlockFactory)

    class Meta:
        model = models.MyBlockItem


class MyCarouselFactory(wagtail_factories.StructBlockFactory):
    title = "Carousel title"
    items = wagtail_factories.ListBlockFactory(
        MyCarouselItemFactory)

    class Meta:
        model = models.MyCarousel


class MyNewsPageFactory(wagtail_factories.PageFactory):
    class Meta:
        model = models.MyNewsPage


class MyNewsPageChooserBlockFactory(wagtail_factories.PageChooserBlockFactory):
    page = factory.SubFactory(MyNewsPageFactory)


class MyTestPageFactory(wagtail_factories.PageFactory):
    body = wagtail_factories.StreamFieldFactory({
        'carousel': factory.SubFactory(MyCarouselFactory),
        'news_page': factory.SubFactory(MyNewsPageChooserBlockFactory),
    })

    class Meta:
        model = models.MyTestPage


def test_my_page():
    root_page = wt_models.Page.get_first_root_node()
    assert root_page is not None

    my_page = MyTestPageFactory(
        parent=root_page,
        title="My great 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",
    )

    # Defaults defined on factory classes are propagated.
    assert my_page.body[0].value["title"] == "Carousel title"

    # Parameters are propagated.
    assert my_page.title == "My great page"
    assert my_page.body[0].value["items"][0].value["label"] == "Slide 1"
```

### Using StreamBlockFactory

`StreamBlockFactory` can be used in conjunction with the other block
factory types to create complex, nested `StreamValues`, much like how
`StreamBlock` can be used to declare the blocks for a complex
`StreamField`.

First, define your `StreamBlockFactory` subclass, using
`factory.SubFactory` to wrap child block declarations. Be sure to
include your `StreamBlock` subclass as the model attribute on the inner
`Meta` class.

``` python
class MyStreamBlockFactory(wagtail_factories.StreamBlockFactory):
    my_struct_block = factory.SubFactory(MyStructBlockFactory)

    class Meta:
        model = MyStreamBlock
```

Then include your `StreamBlockFactory` subclass on a model factory as
the argument to a `StreamFieldFactory`.

``` python
class MyPageFactory(wagtail_factories.PageFactory):
    body = wagtail_factories.StreamFieldFactory(MyStreamBlockFactory)

    class Meta:
        model = MyPage
```

You can then use a modified version of factory\_boy\'s deep object
declaration syntax to build up `StreamValues` on the fly.

``` python
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.

``` python
MyPageFactory(body__0="my_struct_block")
```

### Alternative StreamFieldFactory declaration syntax

Prior to version 3.0, `StreamFieldFactory` could only be used by
providing a dict mapping block names to block factory classes as the
single argument, for example:

``` python
class MyTestPageWithStreamFieldFactory(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,
        }
    )

    class Meta:
        model = models.MyTestPage
```

This style of declaration is still supported, with the caveat that
nested stream blocks are not supported for this approach. From version
3.0, all `BlockFactory` values in a `StreamFieldFactory` definition of
this style *must* be wrapped in factory\_boy `SubFactories`. For
example, the above example must be updated to the following for 3.0
compatibility.

``` python
class MyTestPageWithStreamFieldFactory(wagtail_factories.PageFactory):
    body = wagtail_factories.StreamFieldFactory(
        {
            "char_array": wagta

## Recent releases

| Version | Date | Urgency | Changes |
| --- | --- | --- | --- |
| `v4.5.0` | 2026-06-04 | High | ## What's Changed * Support/wagtail 74 maintenance by @nickmoreton in https://github.com/wagtail/wagtail-factories/pull/116   **Full Changelog**: https://github.com/wagtail/wagtail-factories/compare/v4.4.0...v4.5.0 |
| `4.4.0` | 2026-04-21 | Low | Imported from PyPI (4.4.0) |
| `v4.4.0` | 2026-02-10 | Low | ## What's Changed  * Add developer documentation for StreamField block factories by @jams2 in https://github.com/wagtail/wagtail-factories/pull/102 * Add end-user documentation by @jams2 in https://github.com/wagtail/wagtail-factories/pull/107 * Add support for Wagtail 7 and Python 3.14 by @nickmoreton in https://github.com/wagtail/wagtail-factories/pull/114   **Full Changelog**: https://github.com/wagtail/wagtail-factories/compare/v4.3.0...v4.4.0 |
| `v4.4.0` | 2026-02-10 | Low | ## What's Changed  * Add developer documentation for StreamField block factories by @jams2 in https://github.com/wagtail/wagtail-factories/pull/102 * Add end-user documentation by @jams2 in https://github.com/wagtail/wagtail-factories/pull/107 * Add support for Wagtail 7 and Python 3.14 by @nickmoreton in https://github.com/wagtail/wagtail-factories/pull/114   **Full Changelog**: https://github.com/wagtail/wagtail-factories/compare/v4.3.0...v4.4.0 |
| `v4.4.0` | 2026-02-10 | Low | ## What's Changed  * Add developer documentation for StreamField block factories by @jams2 in https://github.com/wagtail/wagtail-factories/pull/102 * Add end-user documentation by @jams2 in https://github.com/wagtail/wagtail-factories/pull/107 * Add support for Wagtail 7 and Python 3.14 by @nickmoreton in https://github.com/wagtail/wagtail-factories/pull/114   **Full Changelog**: https://github.com/wagtail/wagtail-factories/compare/v4.3.0...v4.4.0 |
| `v4.4.0` | 2026-02-10 | Low | ## What's Changed  * Add developer documentation for StreamField block factories by @jams2 in https://github.com/wagtail/wagtail-factories/pull/102 * Add end-user documentation by @jams2 in https://github.com/wagtail/wagtail-factories/pull/107 * Add support for Wagtail 7 and Python 3.14 by @nickmoreton in https://github.com/wagtail/wagtail-factories/pull/114   **Full Changelog**: https://github.com/wagtail/wagtail-factories/compare/v4.3.0...v4.4.0 |
| `v4.4.0` | 2026-02-10 | Low | ## What's Changed  * Add developer documentation for StreamField block factories by @jams2 in https://github.com/wagtail/wagtail-factories/pull/102 * Add end-user documentation by @jams2 in https://github.com/wagtail/wagtail-factories/pull/107 * Add support for Wagtail 7 and Python 3.14 by @nickmoreton in https://github.com/wagtail/wagtail-factories/pull/114   **Full Changelog**: https://github.com/wagtail/wagtail-factories/compare/v4.3.0...v4.4.0 |
| `v4.4.0` | 2026-02-10 | Low | ## What's Changed  * Add developer documentation for StreamField block factories by @jams2 in https://github.com/wagtail/wagtail-factories/pull/102 * Add end-user documentation by @jams2 in https://github.com/wagtail/wagtail-factories/pull/107 * Add support for Wagtail 7 and Python 3.14 by @nickmoreton in https://github.com/wagtail/wagtail-factories/pull/114   **Full Changelog**: https://github.com/wagtail/wagtail-factories/compare/v4.3.0...v4.4.0 |
| `v4.4.0` | 2026-02-10 | Low | ## What's Changed  * Add developer documentation for StreamField block factories by @jams2 in https://github.com/wagtail/wagtail-factories/pull/102 * Add end-user documentation by @jams2 in https://github.com/wagtail/wagtail-factories/pull/107 * Add support for Wagtail 7 and Python 3.14 by @nickmoreton in https://github.com/wagtail/wagtail-factories/pull/114   **Full Changelog**: https://github.com/wagtail/wagtail-factories/compare/v4.3.0...v4.4.0 |
| `v4.4.0` | 2026-02-10 | Low | ## What's Changed  * Add developer documentation for StreamField block factories by @jams2 in https://github.com/wagtail/wagtail-factories/pull/102 * Add end-user documentation by @jams2 in https://github.com/wagtail/wagtail-factories/pull/107 * Add support for Wagtail 7 and Python 3.14 by @nickmoreton in https://github.com/wagtail/wagtail-factories/pull/114   **Full Changelog**: https://github.com/wagtail/wagtail-factories/compare/v4.3.0...v4.4.0 |

## Citation

- HTML: https://www.freshcrate.ai/projects/wagtail-factories
- Markdown: https://www.freshcrate.ai/projects/wagtail-factories.md
- Dependencies JSON: https://www.freshcrate.ai/api/projects/wagtail-factories/deps

_Generated by freshcrate.ai. Indexes pypi releases for AI-agent ecosystem packages._
