wagtail-factories


Namewagtail-factories JSON
Version 4.3.0 PyPI version JSON
download
home_pagehttps://github.com/wagtail/wagtail-factories/
SummaryFactory boy classes for wagtail
upload_time2025-08-15 08:49:46
maintainerNone
docs_urlNone
authorMichael van Tellingen
requires_pythonNone
licenseMIT
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 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 . 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 = 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),
        }
    )

    class Meta:
        model = models.MyTestPage
```

This requirement does *not* apply to `ListBlockFactory`, which is a
subclass of `SubFactory`.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/wagtail/wagtail-factories/",
    "name": "wagtail-factories",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": null,
    "author": "Michael van Tellingen",
    "author_email": "michaelvantellingen@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/cb/0f/f00ce36a1eaea91075817c65c0c4f6644dc20138e397aafd89afe2e2c3e3/wagtail_factories-4.3.0.tar.gz",
    "platform": null,
    "description": "# wagtail-factories\n\nFactory boy classes for Wagtail CMS\n\n## Installation\n\n``` shell\npip install wagtail-factories\n```\n\n## Usage\n\nDocumentation is still in progress, but see the\n[tests](https://github.com/wagtail/wagtail-factories/tree/main/tests)\nfor more examples.\n\n``` python\nimport wagtail_factories\nfrom . import models\n\n\nclass MyCarouselItemFactory(wagtail_factories.StructBlockFactory):\n    label = 'my-label'\n    image = factory.SubFactory(\n        wagtail_factories.ImageChooserBlockFactory)\n\n    class Meta:\n        model = models.MyBlockItem\n\n\nclass MyCarouselFactory(wagtail_factories.StructBlockFactory):\n    title = \"Carousel title\"\n    items = wagtail_factories.ListBlockFactory(\n        MyCarouselItemFactory)\n\n    class Meta:\n        model = models.MyCarousel\n\n\nclass MyNewsPageFactory(wagtail_factories.PageFactory):\n    class Meta:\n        model = models.MyNewsPage\n\n\nclass MyNewsPageChooserBlockFactory(wagtail_factories.PageChooserBlockFactory):\n    page = factory.SubFactory(MyNewsPageFactory)\n\n\nclass MyTestPageFactory(wagtail_factories.PageFactory):\n    body = wagtail_factories.StreamFieldFactory({\n        'carousel': factory.SubFactory(MyCarouselFactory),\n        'news_page': factory.SubFactory(MyNewsPageChooserBlockFactory),\n    })\n\n    class Meta:\n        model = models.MyTestPage\n\n\ndef test_my_page():\n    root_page = wagtail_factories.PageFactory(parent=None)\n    my_page = MyTestPageFactory(\n        parent=root_page,\n        body__0__carousel__items__0__label='Slide 1',\n        body__0__carousel__items__0__image__image__title='Image Slide 1',\n        body__0__carousel__items__1__label='Slide 2',\n        body__0__carousel__items__1__image__image__title='Image Slide 2',\n        body__0__carousel__items__2__label='Slide 3',\n        body__0__carousel__items__2__image__image__title='Image Slide 3',\n        body__1__news_page__page__title=\"News\",\n    )\n```\n\n### Using StreamBlockFactory\n\n`StreamBlockFactory` can be used in conjunction with the other block\nfactory types to create complex, nested `StreamValues`, much like how\n`StreamBlock` can be used to declare the blocks for a complex\n`StreamField`.\n\nFirst, define your `StreamBlockFactory` subclass, using\n`factory.SubFactory` to wrap child block declarations. Be sure to\ninclude your `StreamBlock` subclass as the model attribute on the inner\n`Meta` class.\n\n``` python\nclass MyStreamBlockFactory(wagtail_factories.StreamBlockFactory):\n    my_struct_block = factory.SubFactory(MyStructBlockFactory)\n\n    class Meta:\n        model = MyStreamBlock\n```\n\nThen include your `StreamBlockFactory` subclass on a model factory as\nthe argument to a `StreamFieldFactory`.\n\n``` python\nclass MyPageFactory(wagtail_factories.PageFactory):\n    body = wagtail_factories.StreamFieldFactory(MyStreamBlockFactory)\n\n    class Meta:\n        model = MyPage\n```\n\nYou can then use a modified version of factory\\_boy\\'s deep object\ndeclaration syntax to build up `StreamValues` on the fly.\n\n``` python\nMyPageFactory(\n    body__0__my_struct_block__some_field=\"some value\",\n    body__0__my_struct_block__some_other_field=\"some other value\",\n)\n```\n\nTo generate the default value for a block factory, terminate your\ndeclaration at the index and provide the block name as the value.\n\n``` python\nMyPageFactory(body__0=\"my_struct_block\")\n```\n\n### Alternative StreamFieldFactory declaration syntax\n\nPrior to version 3.0, `StreamFieldFactory` could only be used by\nproviding a dict mapping block names to block factory classes as the\nsingle argument, for example:\n\n``` python\nclass MyTestPageWithStreamFieldFactory(wagtail_factories.PageFactory):\n    body = wagtail_factories.StreamFieldFactory(\n        {\n            \"char_array\": wagtail_factories.ListBlockFactory(\n                wagtail_factories.CharBlockFactory\n            ),\n            \"int_array\": wagtail_factories.ListBlockFactory(\n                wagtail_factories.IntegerBlockFactory\n            ),\n            \"struct\": MyBlockFactory,\n            \"image\": wagtail_factories.ImageChooserBlockFactory,\n        }\n    )\n\n    class Meta:\n        model = models.MyTestPage\n```\n\nThis style of declaration is still supported, with the caveat that\nnested stream blocks are not supported for this approach. From version\n3.0, all `BlockFactory` values in a `StreamFieldFactory` definition of\nthis style *must* be wrapped in factory\\_boy `SubFactories`. For\nexample, the above example must be updated to the following for 3.0\ncompatibility.\n\n``` python\nclass MyTestPageWithStreamFieldFactory(wagtail_factories.PageFactory):\n    body = wagtail_factories.StreamFieldFactory(\n        {\n            \"char_array\": wagtail_factories.ListBlockFactory(\n                wagtail_factories.CharBlockFactory\n            ),\n            \"int_array\": wagtail_factories.ListBlockFactory(\n                wagtail_factories.IntegerBlockFactory\n            ),\n            \"struct\": factory.SubFactory(MyBlockFactory),\n            \"image\": factory.SubFactory(wagtail_factories.ImageChooserBlockFactory),\n        }\n    )\n\n    class Meta:\n        model = models.MyTestPage\n```\n\nThis requirement does *not* apply to `ListBlockFactory`, which is a\nsubclass of `SubFactory`.\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Factory boy classes for wagtail",
    "version": "4.3.0",
    "project_urls": {
        "Homepage": "https://github.com/wagtail/wagtail-factories/"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "2e5cdc0bcc00512d27423e3bb2b4eee44f3bcbd1c1569910d01d17b6e0e0cc27",
                "md5": "9152b0d075d342dcff002ed6c17330fa",
                "sha256": "6d3129244642a400462344e35168e5eb89598d5b63a4cfb7f26a5a6052f50d95"
            },
            "downloads": -1,
            "filename": "wagtail_factories-4.3.0-py2.py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "9152b0d075d342dcff002ed6c17330fa",
            "packagetype": "bdist_wheel",
            "python_version": "py2.py3",
            "requires_python": null,
            "size": 10513,
            "upload_time": "2025-08-15T08:49:45",
            "upload_time_iso_8601": "2025-08-15T08:49:45.549256Z",
            "url": "https://files.pythonhosted.org/packages/2e/5c/dc0bcc00512d27423e3bb2b4eee44f3bcbd1c1569910d01d17b6e0e0cc27/wagtail_factories-4.3.0-py2.py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "cb0ff00ce36a1eaea91075817c65c0c4f6644dc20138e397aafd89afe2e2c3e3",
                "md5": "dfcbdba4cc1b6dfaf0587a3e16127fcc",
                "sha256": "27c19078ceade5e408aef0edfa3378b7992e5bed4d4c7e8216cbdd53f9732464"
            },
            "downloads": -1,
            "filename": "wagtail_factories-4.3.0.tar.gz",
            "has_sig": false,
            "md5_digest": "dfcbdba4cc1b6dfaf0587a3e16127fcc",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 9613,
            "upload_time": "2025-08-15T08:49:46",
            "upload_time_iso_8601": "2025-08-15T08:49:46.400361Z",
            "url": "https://files.pythonhosted.org/packages/cb/0f/f00ce36a1eaea91075817c65c0c4f6644dc20138e397aafd89afe2e2c3e3/wagtail_factories-4.3.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-15 08:49:46",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "wagtail",
    "github_project": "wagtail-factories",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "wagtail-factories"
}
        
Elapsed time: 4.45735s