-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
155 additions
and
165 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,190 +1,180 @@ | ||
================= | ||
wagtail-factories | ||
================= | ||
# wagtail-factories | ||
|
||
Factory boy classes for Wagtail CMS | ||
|
||
.. start-no-pypi | ||
|
||
Status | ||
------ | ||
|
||
.. image:: https://readthedocs.org/projects/wagtail-factories/badge/?version=latest | ||
:target: https://readthedocs.org/projects/wagtail-factories/ | ||
|
||
.. image:: https://github.com/wagtail/wagtail-factories/workflows/Python%20Tests/badge.svg | ||
:target: https://github.com/wagtail/wagtail-factories/actions?query=workflow%3A%22Python+Tests%22 | ||
|
||
.. image:: https://img.shields.io/pypi/v/wagtail-factories.svg | ||
:target: https://pypi.python.org/pypi/wagtail-factories/ | ||
|
||
|
||
.. end-no-pypi | ||
|
||
|
||
|
||
Installation | ||
============ | ||
|
||
.. code-block:: shell | ||
|
||
pip install wagtail-factories | ||
|
||
|
||
|
||
Usage | ||
===== | ||
|
||
Documentation is still in progress, but see the `tests`_ for more examples. | ||
|
||
.. _tests: https://github.com/wagtail/wagtail-factories/tree/main/tests | ||
|
||
.. code-block:: python | ||
|
||
import wagtail_factories | ||
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 | ||
|
||
Factory boy classes for Wagtail CMS | ||
|
||
class MyNewsPageChooserBlockFactory(wagtail_factories.PageChooserBlockFactory): | ||
page = factory.SubFactory(MyNewsPageFactory) | ||
## Status | ||
|
||
[![image](https://readthedocs.org/projects/wagtail-factories/badge/?version=latest)](https://readthedocs.org/projects/wagtail-factories/) | ||
[![image](https://github.com/wagtail/wagtail-factories/workflows/Python%20Tests/badge.svg)](https://github.com/wagtail/wagtail-factories/actions?query=workflow%3A%22Python+Tests%22) | ||
[![image](https://img.shields.io/pypi/v/wagtail-factories.svg)](https://pypi.python.org/pypi/wagtail-factories/) | ||
|
||
class MyTestPageFactory(wagtail_factories.PageFactory): | ||
body = wagtail_factories.StreamFieldFactory({ | ||
'carousel': factory.SubFactory(MyCarouselFactory), | ||
'news_page': factory.SubFactory(MyNewsPageChooserBlockFactory), | ||
}) | ||
## Installation | ||
|
||
class Meta: | ||
model = models.MyTestPage | ||
``` shell | ||
pip install wagtail-factories | ||
``` | ||
|
||
## Usage | ||
|
||
def test_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", | ||
) | ||
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 . import models | ||
|
||
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``. | ||
class MyCarouselItemFactory(wagtail_factories.StructBlockFactory): | ||
label = 'my-label' | ||
image = factory.SubFactory( | ||
wagtail_factories.ImageChooserBlockFactory) | ||
|
||
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 Meta: | ||
model = models.MyBlockItem | ||
|
||
.. code-block:: python | ||
|
||
class MyStreamBlockFactory(wagtail_factories.StreamBlockFactory): | ||
my_struct_block = factory.SubFactory(MyStructBlockFactory) | ||
class MyCarouselFactory(wagtail_factories.StructBlockFactory): | ||
title = "Carousel title" | ||
items = wagtail_factories.ListBlockFactory( | ||
MyCarouselItemFactory) | ||
|
||
class Meta: | ||
model = MyStreamBlock | ||
class Meta: | ||
model = models.MyCarousel | ||
|
||
|
||
Then include your ``StreamBlockFactory`` subclass on a model factory as the argument to a ``StreamFieldFactory``. | ||
class MyNewsPageFactory(wagtail_factories.PageFactory): | ||
class Meta: | ||
model = models.MyNewsPage | ||
|
||
.. code-block:: python | ||
|
||
class MyPageFactory(wagtail_factories.PageFactory): | ||
body = wagtail_factories.StreamFieldFactory(MyStreamBlockFactory) | ||
class MyNewsPageChooserBlockFactory(wagtail_factories.PageChooserBlockFactory): | ||
page = factory.SubFactory(MyNewsPageFactory) | ||
|
||
class Meta: | ||
model = MyPage | ||
|
||
class MyTestPageFactory(wagtail_factories.PageFactory): | ||
body = wagtail_factories.StreamFieldFactory({ | ||
'carousel': factory.SubFactory(MyCarouselFactory), | ||
'news_page': factory.SubFactory(MyNewsPageChooserBlockFactory), | ||
}) | ||
|
||
You can then use a modified version of factory_boy's deep object declaration syntax to build up ``StreamValues`` on the fly. | ||
class Meta: | ||
model = models.MyTestPage | ||
|
||
.. code-block:: python | ||
|
||
MyPageFactory( | ||
body__0__my_struct_block__some_field="some value", | ||
body__0__my_struct_block__some_other_field="some other value", | ||
def test_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 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": wagtail_factories.ListBlockFactory( | ||
wagtail_factories.CharBlockFactory | ||
), | ||
"int_array": wagtail_factories.ListBlockFactory( | ||
wagtail_factories.IntegerBlockFactory | ||
), | ||
"struct": factory.SubFactory(MyBlockFactory), | ||
"image": factory.SubFactory(wagtail_factories.ImageChooserBlockFactory), | ||
} | ||
) | ||
|
||
To generate the default value for a block factory, terminate your declaration at the index and provide the block name as the value. | ||
|
||
.. code-block:: 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: | ||
|
||
.. code-block:: 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. | ||
|
||
.. code-block:: 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": factory.SubFactory(MyBlockFactory), | ||
"image": factory.SubFactory(wagtail_factories.ImageChooserBlockFactory), | ||
} | ||
) | ||
|
||
class Meta: | ||
model = models.MyTestPage | ||
|
||
class Meta: | ||
model = models.MyTestPage | ||
``` | ||
|
||
This requirement does *not* apply to ``ListBlockFactory``, which is a subclass of ``SubFactory``. | ||
This requirement does *not* apply to `ListBlockFactory`, which is a | ||
subclass of `SubFactory`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters