wagtail-factories
Factory boy classes for Wagtail CMS
Installation
pip install wagtail-factories
Usage
Documentation is still in progress, but see the tests for more examples.
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.
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.
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.
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 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:
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.
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": factory.SubFactory(MyBlockFactory),
"image": factory.SubFactory(wagtail_factories.ImageChooserBlockFactory),
}
)
class Meta:
model = models.MyTestPage
This requirement does not apply to ListBlockFactory, which is a
subclass of SubFactory.
Metadata
Release files for wagtail-factories 4.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| wagtail_factories-4.5.0.tar.gz | 10.1 kB | Without provenance | Details for wagtail_factories-4.5.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| wagtail_factories-4.5.0-py3-none-any.whl | Python 3 | none | any | Details for wagtail_factories-4.5.0-py3-none-any.whl |
Total release size: 20.9 kB
Release files / wagtail_factories-4.5.0.tar.gz
| Download URL | wagtail_factories-4.5.0.tar.gz |
|---|---|
| Size | 10.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d981ceaaf7715b2325f9debb1be1ffc07e338ae8957e9527f4f9175fcdff2c56
|
|
BLAKE2b-256 checksum How to use checksums |
0cb80a6e91ea32467acd96c5769face88c6ac79f2f0990f822d7396d054bbc15
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Release files / wagtail_factories-4.5.0-py3-none-any.whl
| Download URL | wagtail_factories-4.5.0-py3-none-any.whl |
|---|---|
| Size | 10.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4ad0e9f396fca7f7d349a8752c49f68e18deeffee9c857897b849ff08c6c33a6
|
|
BLAKE2b-256 checksum How to use checksums |
8f1836e0be763870e22b1f0f87361cc768a7bfcc842f6504a6bafdddf932fd7d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Security for wagtail-factories 4.5.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.