Skip to content

Django Factories

Related links

What

Library we use: factory_boy - https://factoryboy.readthedocs.io/en/stable/index.html

Why

  • Create instances of models with realistic mock data
  • Useful when creating mock data in tests

Example

Example model - Dashboard - can have many Page

Without Factory

Two pages on the same dashboard

from .models import Dashboard, Page

dashboard = Dashboard.objects.create(
    name="dashboard-name",
    ...
)

page1 = Page.objects.create(
    name="Page name 1",
    dashboard=dashboard,
    ...
)

page2 = Page.objects.create(
    name="Page name 2",
    dashboard=dashboard,
    ...
)

With Factory

PageFactory creates a dashboard if one isn't passed in

page1 = PageFactory()
page2 = PageFactory(dashboard=page1.dashboard)

Creating a Factory

factory_boy uses faker to generate mock data

import factory
from faker import Faker

from .models import Page
from .factories import DashboardFactory

faker = Faker()


class PageFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = ModelName

    # don't need to generate the ID if it's auto incrementing

    name = factory.LazyAttributeSequence(lambda o, n: f"name_{n}")

    # will generate a Dashboard if dashboard isn't provided
    dashboard = factory.SubFactory(DashboardFactory)

Lazy means that a new value will be generated for every new Page created by PageFactory

Other useful factory helpers

price = factory.LazyAttribute(lambda: random.randrange(MIN_PRICE, MAX_PRICE + 1))
.create() vs .build()

PageFactory() <==> PageFactory.create()

PageFactory.create() creates a page

PageFactory.build() doesn't call .save() so no database entry is created in the database


Last update: 2022-09-23