Skip to content

Django Factories

Related links

What

Library we use: factory_boy

Why

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

Example

Example model

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 bulk instances

MyFactory.create_batch(5)

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

    # o: the current instance object
    name = factory.Sequence(lambda n: f"name_{n}")
    shard = factory.LazyFunction(lambda: )

    # 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: 2023-04-24