Reference

This section offers an in-depth description of factory_boy features.

For internals and customization points, please refer to the Internals section.

The Factory class

Meta options

class factory.FactoryOptions

New in version 2.4.0.

A Factory’s behavior can be tuned through a few settings.

For convenience, they are declared in a single class Meta attribute:

class MyFactory(factory.Factory):
    class Meta:
        model = MyObject
        abstract = False
model

This optional attribute describes the class of objects to generate.

If unset, it will be inherited from parent Factory subclasses.

New in version 2.4.0.

get_model_class()

Returns the actual model class (FactoryOptions.model might be the path to the class; this function will always return a proper class).

abstract

This attribute indicates that the Factory subclass should not be used to generate objects, but instead provides some extra defaults.

It will be automatically set to True if neither the Factory subclass nor its parents define the model attribute.

Warning

This flag is reset to False when a Factory subclasses another one if a model is set.

New in version 2.4.0.

inline_args

Some factories require non-keyword arguments to their __init__(). They should be listed, in order, in the inline_args attribute:

class UserFactory(factory.Factory):
    class Meta:
        model = User
        inline_args = ('login', 'email')

    login = 'john'
    email = factory.LazyAttribute(lambda o: '%s@example.com' % o.login)
    firstname = "John"
>>> UserFactory()
<User: john>
>>> User('john', 'john@example.com', firstname="John")  # actual call

New in version 2.4.0.

exclude

While writing a Factory for some object, it may be useful to have general fields helping defining others, but that should not be passed to the model class; for instance, a field named ‘now’ that would hold a reference time used by other objects.

Factory fields whose name are listed in exclude will be removed from the set of args/kwargs passed to the underlying class; they can be any valid factory_boy declaration:

class OrderFactory(factory.Factory):
    class Meta:
        model = Order
        exclude = ('now',)

    now = factory.LazyFunction(datetime.datetime.utcnow)
    started_at = factory.LazyAttribute(lambda o: o.now - datetime.timedelta(hours=1))
    paid_at = factory.LazyAttribute(lambda o: o.now - datetime.timedelta(minutes=50))
>>> OrderFactory()    # The value of 'now' isn't passed to Order()
<Order: started 2013-04-01 12:00:00, paid 2013-04-01 12:10:00>

>>> # An alternate value may be passed for 'now'
>>> OrderFactory(now=datetime.datetime(2013, 4, 1, 10))
<Order: started 2013-04-01 09:00:00, paid 2013-04-01 09:10:00>

New in version 2.4.0.

rename

Sometimes, a model expects a field with a name already used by one of Factory’s methods.

In this case, the rename attributes allows to define renaming rules: the keys of the rename dict are those used in the Factory declarations, and their values the new name:

class ImageFactory(factory.Factory):
    # The model expects "attributes"
    form_attributes = ['thumbnail', 'black-and-white']

    class Meta:
        model = Image
        rename = {'form_attributes': 'attributes'}
strategy

Use this attribute to change the strategy used by a Factory. The default is CREATE_STRATEGY.

Attributes and methods

class factory.Factory[source]

Class-level attributes:

Meta
_meta

New in version 2.4.0.

The FactoryOptions instance attached to a Factory class is available as a _meta attribute.

Params

New in version 2.7.0.

The extra parameters attached to a Factory are declared through a Params class. See the “Parameters” section for more information.

_options_class

New in version 2.4.0.

If a Factory subclass needs to define additional, extra options, it has to provide a custom FactoryOptions subclass.

A pointer to that custom class should be provided as _options_class so that the Factory-building metaclass can use it instead.

Base functions:

The Factory class provides a few methods for getting objects; the usual way being to simply call the class:

>>> UserFactory()               # Calls UserFactory.create()
>>> UserFactory(login='john')   # Calls UserFactory.create(login='john')

Under the hood, factory_boy will define the Factory __new__() method to call the default strategy of the Factory.

A specific strategy for getting instance can be selected by calling the adequate method:

classmethod build(cls, **kwargs)

Provides a new object, using the ‘build’ strategy.

classmethod build_batch(cls, size, **kwargs)

Provides a list of size instances from the Factory, through the ‘build’ strategy.

classmethod create(cls, **kwargs)

Provides a new object, using the ‘create’ strategy.

classmethod create_batch(cls, size, **kwargs)

Provides a list of size instances from the Factory, through the ‘create’ strategy.

classmethod stub(cls, **kwargs)

Provides a new stub

classmethod stub_batch(cls, size, **kwargs)

Provides a list of size stubs from the Factory.

classmethod generate(cls, strategy, **kwargs)

Provide a new instance, with the provided strategy.

classmethod generate_batch(cls, strategy, size, **kwargs)

Provides a list of size instances using the specified strategy.

classmethod simple_generate(cls, create, **kwargs)

Provide a new instance, either built (create=False) or created (create=True).

classmethod simple_generate_batch(cls, create, size, **kwargs)

Provides a list of size instances, either built or created according to create.

Extension points:

A Factory subclass may override a couple of class methods to adapt its behavior:

classmethod _adjust_kwargs(cls, **kwargs)

The _adjust_kwargs() extension point allows for late fields tuning.

It is called once keyword arguments have been resolved and post-generation items removed, but before the inline_args extraction phase.

class UserFactory(factory.Factory):

    @classmethod
    def _adjust_kwargs(cls, **kwargs):
        # Ensure ``lastname`` is upper-case.
        kwargs['lastname'] = kwargs['lastname'].upper()
        return kwargs
classmethod _setup_next_sequence(cls)

This method will compute the first value to use for the sequence counter of this factory.

It is called when the first instance of the factory (or one of its subclasses) is created.

Subclasses may fetch the next free ID from the database, for instance.

classmethod _build(cls, model_class, *args, **kwargs)

This class method is called whenever a new instance needs to be built. It receives the model class (provided to model), and the positional and keyword arguments to use for the class once all has been computed.

Subclasses may override this for custom APIs.

classmethod _create(cls, model_class, *args, **kwargs)

The _create() method is called whenever an instance needs to be created. It receives the same arguments as _build().

Subclasses may override this for specific persistence backends:

class BaseBackendFactory(factory.Factory):
    class Meta:
        abstract = True  # Optional

    @classmethod
    def _create(cls, model_class, *args, **kwargs):
        obj = model_class(*args, **kwargs)
        obj.save()
        return obj
classmethod _after_postgeneration(cls, obj, create, results=None)
Parameters:
  • obj (object) – The object just generated

  • create (bool) – Whether the object was ‘built’ or ‘created’

  • results (dict) – Map of post-generation declaration name to call result

The _after_postgeneration() is called once post-generation declarations have been handled.

Its arguments allow to handle specifically some post-generation return values, for instance.

Advanced functions:

classmethod reset_sequence(cls, value=None, force=False)
Parameters:
  • value (int) – The value to reset the sequence to

  • force (bool) – Whether to force-reset the sequence

Allows to reset the sequence counter for a Factory. The new value can be passed in as the value argument:

>>> SomeFactory.build().sequenced_attribute
0
>>> SomeFactory.reset_sequence(4)
>>> SomeFactory.build().sequenced_attribute
4

Since subclasses of a non-abstract Factory share the same sequence counter, special care needs to be taken when resetting the counter of such a subclass.

By default, reset_sequence() will raise a ValueError when called on a subclassed Factory subclass. This can be avoided by passing in the force=True flag:

>>> InheritedFactory.reset_sequence()
Traceback (most recent call last):
  File "factory_boy/tests/test_base.py", line 179, in test_reset_sequence_subclass_parent
    SubTestObjectFactory.reset_sequence()
  File "factory_boy/factory/base.py", line 250, in reset_sequence
    "Cannot reset the sequence of a factory subclass. "
ValueError: Cannot reset the sequence of a factory subclass. Please call reset_sequence() on the root factory, or call reset_sequence(forward=True).

>>> InheritedFactory.reset_sequence(force=True)
>>>

This is equivalent to calling reset_sequence() on the base factory in the chain.

Parameters

New in version 2.7.0.

Some models have many fields that can be summarized by a few parameters; for instance, a train with many cars — each complete with serial number, manufacturer, …; or an order that can be pending/shipped/received, with a few fields to describe each step.

When building instances of such models, a couple of parameters can be enough to determine all other fields; this is handled by the Params section of a Factory declaration.

Simple parameters

Some factories only need little data:

class ConferenceFactory(factory.Factory):
    class Meta:
        model = Conference

    class Params:
        duration = 'short' # Or 'long'

    start_date = factory.fuzzy.FuzzyDate()
    end_date = factory.LazyAttribute(
        lambda o: o.start_date + datetime.timedelta(days=2 if o.duration == 'short' else 7)
    )
    sprints_start = factory.LazyAttribute(
        lambda o: o.end_date - datetime.timedelta(days=0 if o.duration == 'short' else 1)
    )
>>> ConferenceFactory(duration='short')
<Conference: DUTH 2015 (2015-11-05 - 2015-11-08, sprints 2015-11-08)>
>>> ConferenceFactory(duration='long')
<Conference: DjangoConEU 2016 (2016-03-30 - 2016-04-03, sprints 2016-04-02)>

Any simple parameter provided to the Factory.Params section is available to the whole factory, but not passed to the final class (similar to the exclude behavior).

Traits

class factory.Trait(**kwargs)[source]

New in version 2.7.0.

A trait’s parameters are the fields it should alter when enabled.

For more complex situations, it is helpful to override a few fields at once:

class OrderFactory(factory.Factory):
    class Meta:
        model = Order

    state = 'pending'
    shipped_on = None
    shipped_by = None

    class Params:
        shipped = factory.Trait(
            state='shipped',
            shipped_on=datetime.date.today(),
            shipped_by=factory.SubFactory(EmployeeFactory),
        )

Such a Trait is activated or disabled by a single boolean field:

>>> OrderFactory()
<Order: pending>
Order(state='pending')
>>> OrderFactory(shipped=True)
<Order: shipped by John Doe on 2016-04-02>

A Trait can be enabled/disabled by a Factory subclass:

class ShippedOrderFactory(OrderFactory):
    shipped = True

Values set in a Trait can be overridden by call-time values:

>>> OrderFactory(shipped=True, shipped_on=last_year)
<Order: shipped by John Doe on 2015-04-20>

Traits can be chained:

class OrderFactory(factory.Factory):
    class Meta:
        model = Order

    # Can be pending/shipping/received
    state = 'pending'
    shipped_on = None
    shipped_by = None
    received_on = None
    received_by = None

    class Params:
        shipped = factory.Trait(
            state='shipped',
            shipped_on=datetime.date.today,
            shipped_by=factory.SubFactory(EmployeeFactory),
        )
        received = factory.Trait(
            shipped=True,
            state='received',
            shipped_on=datetime.date.today - datetime.timedelta(days=4),
            received_on=datetime.date.today,
            received_by=factory.SubFactory(CustomerFactory),
        )
>>> OrderFactory(received=True)
<Order: shipped by John Doe on 2016-03-20, received by Joan Smith on 2016-04-02>

A Trait might be overridden in Factory subclasses:

class LocalOrderFactory(OrderFactory):

    class Params:
        received = factory.Trait(
            shipped=True,
            state='received',
            shipped_on=datetime.date.today - datetime.timedelta(days=1),
            received_on=datetime.date.today,
            received_by=factory.SubFactory(CustomerFactory),
        )
>>> LocalOrderFactory(received=True)
<Order: shipped by John Doe on 2016-04-01, received by Joan Smith on 2016-04-02>

Note

When overriding a Trait, the whole declaration MUST be replaced.

Strategies

factory_boy supports two main strategies for generating instances, plus stubs.

factory.BUILD_STRATEGY

The ‘build’ strategy is used when an instance should be created, but not persisted to any datastore.

It is usually a simple call to the __init__() method of the model class.

factory.CREATE_STRATEGY

The ‘create’ strategy builds and saves an instance into its appropriate datastore.

This is the default strategy of factory_boy; it would typically instantiate an object, then save it:

>>> obj = self._associated_class(*args, **kwargs)
>>> obj.save()
>>> return obj

Warning

For backward compatibility reasons, the default behavior of factory_boy is to call MyClass.objects.create(*args, **kwargs) when using the create strategy.

That policy will be used if the associated class has an objects attribute and the _create() classmethod of the Factory wasn’t overridden.

factory.use_strategy(strategy)[source]

Deprecated since version 3.2: Use factory.FactoryOptions.strategy instead.

Decorator

Change the default strategy of the decorated Factory to the chosen strategy:

@use_strategy(factory.BUILD_STRATEGY)
class UserBuildingFactory(UserFactory):
    pass
factory.STUB_STRATEGY

The ‘stub’ strategy is an exception in the factory_boy world: it doesn’t return an instance of the model class, and actually doesn’t require one to be present.

Instead, it returns an instance of StubObject whose attributes have been set according to the declarations.

class factory.StubObject

A plain, stupid object. No method, no helpers, simply a bunch of attributes.

It is typically instantiated, then has its attributes set:

>>> obj = StubObject()
>>> obj.x = 1
>>> obj.y = 2
class factory.StubFactory(Factory)[source]

An abstract Factory, with a default strategy set to STUB_STRATEGY.

factory.debug(logger='factory', stream=None)[source]
Parameters:
  • logger (str) – The name of the logger to enable debug for

  • stream (file) – The stream to send debug output to, defaults to sys.stderr

Context manager to help debugging factory_boy behavior. It will temporarily put the target logger (e.g 'factory') in debug mode, sending all output to stream; upon leaving the context, the logging levels are reset.

A typical use case is to understand what happens during a single factory call:

with factory.debug():
    obj = TestModel2Factory()

This will yield messages similar to those (artificial indentation):

BaseFactory: Preparing tests.test_using.TestModel2Factory(extra={})
  LazyStub: Computing values for tests.test_using.TestModel2Factory(two=<OrderedDeclarationWrapper for <factory.declarations.SubFactory object at 0x1e15610>>)
    SubFactory: Instantiating tests.test_using.TestModelFactory(__containers=(<LazyStub for tests.test_using.TestModel2Factory>,), one=4), create=True
    BaseFactory: Preparing tests.test_using.TestModelFactory(extra={'__containers': (<LazyStub for tests.test_using.TestModel2Factory>,), 'one': 4})
      LazyStub: Computing values for tests.test_using.TestModelFactory(one=4)
      LazyStub: Computed values, got tests.test_using.TestModelFactory(one=4)
    BaseFactory: Generating tests.test_using.TestModelFactory(one=4)
  LazyStub: Computed values, got tests.test_using.TestModel2Factory(two=<tests.test_using.TestModel object at 0x1e15410>)
BaseFactory: Generating tests.test_using.TestModel2Factory(two=<tests.test_using.TestModel object at 0x1e15410>)

Declarations

Faker

class factory.Faker(provider, locale=None, **kwargs)[source]

In order to easily define realistic-looking factories, use the Faker attribute declaration.

This is a wrapper around faker; its argument is the name of a faker provider:

class UserFactory(factory.Factory):
    class Meta:
        model = User

    name = factory.Faker('name')
>>> user = UserFactory()
>>> user.name
'Lucy Cechtelar'

Some providers accept parameters; they should be passed after the provider name:

class UserFactory(factory.Factory):
    class Meta:
        model = User

    arrival = factory.Faker(
        'date_between_dates',
        date_start=datetime.date(2020, 1, 1),
        date_end=datetime.date(2020, 5, 31),
    )

As with SubFactory, the parameters can be any valid declaration. This does not apply to the provider name or the locale.

class TripFactory(factory.Factory):
    class Meta:
        model = Trip

    departure = factory.Faker(
        'date',
        end_datetime=datetime.date.today(),
    )
    arrival = factory.Faker(
        'date_between_dates',
        date_start=factory.SelfAttribute('..departure'),
    )

Note

When using SelfAttribute or LazyAttribute in a factory.Faker parameter, the current object is the declarations provided to the Faker declaration; go up a level to reach fields of the surrounding Factory, as shown in the SelfAttribute('..xxx') example above.

locale

If a custom locale is required for one specific field, use the locale parameter:

class UserFactory(factory.Factory):
    class Meta:
        model = User

    name = factory.Faker('name', locale='fr_FR')
>>> user = UserFactory()
>>> user.name
'Jean Valjean'
classmethod override_default_locale(cls, locale)[source]

If the locale needs to be overridden for a whole test, use override_default_locale():

>>> with factory.Faker.override_default_locale('de_DE'):
...     UserFactory()
<User: Johannes Brahms>
classmethod add_provider(cls, locale=None)[source]

Some projects may need to fake fields beyond those provided by faker; in such cases, use factory.Faker.add_provider() to declare additional providers for those fields:

factory.Faker.add_provider(SmileyProvider)

class FaceFactory(factory.Factory):
    class Meta:
        model = Face

    smiley = factory.Faker('smiley')

LazyFunction

class factory.LazyFunction(method_to_call)[source]

The LazyFunction is the simplest case where the value of an attribute does not depend on the object being built.

It takes as an argument a function to call; that should not take any arguments and return a value.

class LogFactory(factory.Factory):
    class Meta:
        model = models.Log

    timestamp = factory.LazyFunction(datetime.now)
>>> LogFactory()
<Log: log at 2016-02-12 17:02:34>

>>> # The LazyFunction can be overridden
>>> LogFactory(timestamp=now - timedelta(days=1))
<Log: log at 2016-02-11 17:02:34>

LazyFunction is also useful for assigning copies of mutable objects (like lists) to an object’s property. Example:

DEFAULT_TEAM = ['Player1', 'Player2']

class TeamFactory(factory.Factory):
    class Meta:
        model = models.Team

    teammates = factory.LazyFunction(lambda: list(DEFAULT_TEAM))

Decorator

The class LazyFunction does not provide a decorator.

For complex cases, use LazyAttribute.lazy_attribute() directly.

LazyAttribute

class factory.LazyAttribute(method_to_call)[source]

The LazyAttribute is a simple yet extremely powerful building brick for extending a Factory.

It takes as argument a method to call (usually a lambda); that method should accept the object being built as sole argument, and return a value.

class UserFactory(factory.Factory):
    class Meta:
        model = User

    username = 'john'
    email = factory.LazyAttribute(lambda o: '%s@example.com' % o.username)
>>> u = UserFactory()
>>> u.email
'john@example.com'

>>> u = UserFactory(username='leo')
>>> u.email
'leo@example.com'

The object passed to LazyAttribute is not an instance of the target class, but instead a Resolver: a temporary container that computes the value of all declared fields.

Decorator

factory.lazy_attribute()[source]

If a simple lambda isn’t enough, you may use the lazy_attribute() decorator instead.

This decorates an instance method that should take a single argument, self; the name of the method will be used as the name of the attribute to fill with the return value of the method:

class UserFactory(factory.Factory)
    class Meta:
        model = User

    name = "Jean"

    @factory.lazy_attribute
    def email(self):
        # Convert to plain ascii text
        clean_name = (unicodedata.normalize('NFKD', self.name)
                        .encode('ascii', 'ignore')
                        .decode('utf8'))
        return '%s@example.com' % clean_name
>>> joel = UserFactory(name="Joël")
>>> joel.email
'joel@example.com'

Transformer

class factory.Transformer(default_value, *, transform)[source]

A Transformer applies a transform function to the provided value before to set the transformed value on the generated object.

It expects one positional argument and one keyword argument:

  • default_value: the default value, which passes through the transform function.

  • transform: a function taking the value as parameter and returning the transformed value,

class UpperFactory(factory.Factory):
    name = factory.Transformer("Joe", transform=str.upper)

    class Meta:
        model = Upper
>>> UpperFactory().name
'JOE'
>>> UpperFactory(name="John").name
'JOHN'

Disabling

To disable a Transformer, wrap the value in Transformer.Force:

>>> UpperFactory(name=factory.Transformer.Force("John")).name
'John'

Sequence

class factory.Sequence(lambda)[source]

If a field should be unique, and thus different for all built instances, use a Sequence.

This declaration takes a single argument, a function accepting a single parameter - the current sequence counter - and returning the related value.

class UserFactory(factory.Factory)
    class Meta:
        model = User

    phone = factory.Sequence(lambda n: '123-555-%04d' % n)
>>> UserFactory().phone
'123-555-0000'
>>> UserFactory().phone
'123-555-0001'

Note

The sequence counter starts at 0 and can be set or reset, see Forcing a sequence counter.

Decorator

factory.sequence()[source]

As with lazy_attribute(), a decorator is available for complex situations.

sequence() decorates an instance method, whose self method will actually be the sequence counter - this might be confusing:

class UserFactory(factory.Factory)
    class Meta:
        model = User

    @factory.sequence
    def phone(n):
        a = n // 10000
        b = n % 10000
        return '%03d-555-%04d' % (a, b)
>>> UserFactory().phone  # current sequence counter at 9999
'000-555-9999'
>>> UserFactory().phone  # current sequence counter at 10000
'001-555-0000'

Sharing

The sequence counter is shared across all Sequence attributes of the Factory:

class UserFactory(factory.Factory):
    class Meta:
        model = User

    phone = factory.Sequence(lambda n: '%04d' % n)
    office = factory.Sequence(lambda n: 'A23-B%03d' % n)
>>> u = UserFactory()
>>> u.phone, u.office
'0040', 'A23-B040'
>>> u2 = UserFactory()
>>> u2.phone, u2.office
'0041', 'A23-B041'

Inheritance

When a Factory inherits from another Factory and the model of the subclass inherits from the model of the parent, the sequence counter is shared across the Factory classes:

class UserFactory(factory.Factory):
    class Meta:
        model = User

    phone = factory.Sequence(lambda n: '123-555-%04d' % n)


class EmployeeFactory(UserFactory):
    office_phone = factory.Sequence(lambda n: '%04d' % n)
>>> u = UserFactory()
>>> u.phone
'123-555-0000'

>>> e = EmployeeFactory()
>>> e.phone, e.office_phone
'123-555-0001', '0001'

>>> u2 = UserFactory()
>>> u2.phone
'123-555-0002'

Forcing a sequence counter

If a specific value of the sequence counter is required for one instance, the __sequence keyword argument should be passed to the factory method.

This will force the sequence counter during the call, without altering the class-level value.

class UserFactory(factory.Factory):
    class Meta:
        model = User

    uid = factory.Sequence(int)
>>> UserFactory()
<User: 0>
>>> UserFactory()
<User: 1>
>>> UserFactory(__sequence=42)
<User: 42>

Warning

The impact of setting __sequence=n on a _batch call is undefined. Each generated instance may share a same counter, or use incremental values starting from the forced value.

LazyAttributeSequence

class factory.LazyAttributeSequence(method_to_call)[source]

The LazyAttributeSequence declaration merges features of Sequence and LazyAttribute.

It takes a single argument, a function whose two parameters are, in order:

  • The object being built

  • The sequence counter

class UserFactory(factory.Factory):
    class Meta:
        model = User

    login = 'john'
    email = factory.LazyAttributeSequence(lambda o, n: '%s@s%d.example.com' % (o.login, n))
>>> UserFactory().email
'john@s0.example.com'
>>> UserFactory(login='jack').email
'jack@s1.example.com'

Decorator

factory.lazy_attribute_sequence(method_to_call)[source]

As for lazy_attribute() and sequence(), the lazy_attribute_sequence() handles more complex cases:

class UserFactory(factory.Factory):
    class Meta:
        model = User

    login = 'john'

    @lazy_attribute_sequence
    def email(self, n):
        bucket = n % 10
        return '%s@s%d.example.com' % (self.login, bucket)

SubFactory

class factory.SubFactory(factory, **kwargs)[source]

This attribute declaration calls another Factory subclass, selecting the same build strategy and collecting extra kwargs in the process.

The SubFactory attribute should be called with:

  • A Factory subclass as first argument, or the fully qualified import path to that Factory (see Circular imports)

  • An optional set of keyword arguments that should be passed when calling that factory

Note

When passing an actual Factory for the factory argument, make sure to pass the class and not instance (i.e no () after the class):

class FooFactory(factory.Factory):
    class Meta:
        model = Foo

    bar = factory.SubFactory(BarFactory)  # Not BarFactory()

Definition

# A standard factory
class UserFactory(factory.Factory):
    class Meta:
        model = User

    # Various fields
    first_name = 'John'
    last_name = factory.Sequence(lambda n: 'D%se' % ('o' * n))  # De, Doe, Dooe, Doooe, ...
    email = factory.LazyAttribute(lambda o: '%s.%s@example.org' % (o.first_name.lower(), o.last_name.lower()))

# A factory for an object with a 'User' field
class CompanyFactory(factory.Factory):
    class Meta:
        model = Company

    name = factory.Sequence(lambda n: 'FactoryBoyz' + 'z' * n)

    # Let's use our UserFactory to create that user, and override its first name.
    owner = factory.SubFactory(UserFactory, first_name='Jack')

Calling

The wrapping factory will call of the inner factory:

>>> c = CompanyFactory()
>>> c
<Company: FactoryBoyz>

# Notice that the first_name was overridden
>>> c.owner
<User: Jack De>
>>> c.owner.email
jack.de@example.org

Fields of the SubFactory may be overridden from the external factory:

>>> c = CompanyFactory(owner__first_name='Henry')
>>> c.owner
<User: Henry Doe>

# Notice that the updated first_name was propagated to the email LazyAttribute.
>>> c.owner.email
henry.doe@example.org

# It is also possible to override other fields of the SubFactory
>>> c = CompanyFactory(owner__last_name='Jones')
>>> c.owner
<User: Henry Jones>
>>> c.owner.email
henry.jones@example.org

Strategies

The strategy chosen for the external factory will be propagated to all subfactories:

>>> c = CompanyFactory()
>>> c.pk            # Saved to the database
3
>>> c.owner.pk      # Saved to the database
8

>>> c = CompanyFactory.build()
>>> c.pk            # Not saved
None
>>> c.owner.pk      # Not saved either
None

Circular imports

Some factories may rely on each other in a circular manner. This issue can be handled by passing the absolute import path to the target Factory to the SubFactory.

New in version 1.3.0.

class UserFactory(factory.Factory):
    class Meta:
        model = User

    username = 'john'
    main_group = factory.SubFactory('users.factories.GroupFactory')

class GroupFactory(factory.Factory):
    class Meta:
        model = Group

    name = "MyGroup"
    owner = factory.SubFactory(UserFactory)

Obviously, such circular relationships require careful handling of loops:

>>> owner = UserFactory(main_group=None)
>>> UserFactory(main_group__owner=owner)
<john (group: MyGroup)>

SelfAttribute

class factory.SelfAttribute(dotted_path_to_attribute)[source]

Some fields should reference another field of the object being constructed, or an attribute thereof.

This is performed by the SelfAttribute declaration. That declaration takes a single argument, a dot-delimited path to the attribute to fetch:

class UserFactory(factory.Factory):
    class Meta:
        model = User

    birthdate = factory.fuzzy.FuzzyDate()
    birthmonth = factory.SelfAttribute('birthdate.month')
>>> u = UserFactory()
>>> u.birthdate
date(2000, 3, 15)
>>> u.birthmonth
3

Parents

When used in conjunction with SubFactory, the SelfAttribute gains an “upward” semantic through the double-dot notation, as used in Python imports.

factory.SelfAttribute('..country.language') means “Select the language of the country of the Factory calling me”.

class UserFactory(factory.Factory):
    class Meta:
        model = User

    language = 'en'


class CompanyFactory(factory.Factory):
    class Meta:
        model = Company

    country = factory.SubFactory(CountryFactory)
    owner = factory.SubFactory(UserFactory, language=factory.SelfAttribute('..country.language'))
>>> company = CompanyFactory()
>>> company.country.language
'fr'
>>> company.owner.language
'fr'

Obviously, this “follow parents” ability also handles overriding some attributes on call:

>>> company = CompanyFactory(country=china)
>>> company.owner.language
'cn'

This feature is also available to LazyAttribute and LazyAttributeSequence, through the factory_parent attribute of the passed-in object:

class CompanyFactory(factory.Factory):
    class Meta:
        model = Company
    country = factory.SubFactory(CountryFactory)
    owner = factory.SubFactory(UserFactory,
        language=factory.LazyAttribute(lambda user: user.factory_parent.country.language),
    )

Iterator

class factory.Iterator(iterable, cycle=True, getter=None)[source]

The Iterator declaration takes successive values from the given iterable. When it is exhausted, it starts again from zero (unless cycle=False).

cycle

The cycle argument is only useful for advanced cases, where the provided iterable has no end (as wishing to cycle it means storing values in memory…).

New in version 1.3.0: The cycle argument is available as of v1.3.0; previous versions had a behavior equivalent to cycle=False.

getter

A custom function called on each value returned by the iterable. See the Getter section for details.

New in version 1.3.0.

reset()[source]

Reset the internal iterator used by the attribute, so that the next value will be the first value generated by the iterator.

May be called several times.

Each call to the factory will receive the next value from the iterable:

class UserFactory(factory.Factory)
    lang = factory.Iterator(['en', 'fr', 'es', 'it', 'de'])
>>> UserFactory().lang
'en'
>>> UserFactory().lang
'fr'

When a value is passed in for the argument, the iterator will not be advanced:

>>> UserFactory().lang
'en'
>>> UserFactory(lang='cn').lang
'cn'
>>> UserFactory().lang
'fr'

Getter

Some situations may reuse an existing iterable, using only some component. This is handled by the getter attribute: this is a function that accepts as sole parameter a value from the iterable, and returns an adequate value.

class UserFactory(factory.Factory):
    class Meta:
        model = User

    # CATEGORY_CHOICES is a list of (key, title) tuples
    category = factory.Iterator(User.CATEGORY_CHOICES, getter=lambda c: c[0])

Decorator

factory.iterator(func)[source]

When generating items of the iterator gets too complex for a simple list comprehension, use the iterator() decorator:

Warning

The decorated function takes no argument, notably no self parameter.

class UserFactory(factory.Factory):
    class Meta:
        model = User

    @factory.iterator
    def name():
        with open('test/data/names.dat', 'r') as f:
            for line in f:
                yield line

Warning

Values from the underlying iterator are kept in memory; once the initial iterator has been emptied, saved values are used instead of executing the function instead.

Use factory.Iterator(my_func, cycle=False) to disable value recycling.

Resetting

In order to start back at the first value in an Iterator, simply call the reset() method of that attribute (accessing it from the bare Factory subclass):

>>> UserFactory().lang
'en'
>>> UserFactory().lang
'fr'
>>> UserFactory.lang.reset()
>>> UserFactory().lang
'en'

Dict and List

When a factory expects lists or dicts as arguments, such values can be generated through the whole range of factory_boy declarations, with the Dict and List attributes:

class factory.Dict(params[, dict_factory=factory.DictFactory])[source]

The Dict class is used for dict-like attributes. It receives as non-keyword argument a dictionary of fields to define, whose value may be any factory-enabled declarations:

class UserFactory(factory.Factory):
    class Meta:
        model = User

    is_superuser = False
    roles = factory.Dict({
        'role1': True,
        'role2': False,
        'role3': factory.Iterator([True, False]),
        'admin': factory.SelfAttribute('..is_superuser'),
    })

Note

Declarations used as a Dict values are evaluated within that Dict’s context; this means that you must use the ..foo syntax to access fields defined at the factory level.

On the other hand, the Sequence counter is aligned on the containing factory’s one.

The Dict behavior can be tuned through the following parameters:

dict_factory

The actual factory to use for generating the dict can be set as a keyword argument, if an exotic dictionary-like object (SortedDict, …) is required.

class factory.List(items[, list_factory=factory.ListFactory])[source]

The List can be used for list-like attributes.

Internally, the fields are converted into a index=value dict, which makes it possible to override some values at use time:

class UserFactory(factory.Factory):
    class Meta:
        model = User

    flags = factory.List([
        'user',
        'active',
        'admin',
    ])
>>> u = UserFactory(flags__2='superadmin')
>>> u.flags
['user', 'active', 'superadmin']

The List behavior can be tuned through the following parameters:

list_factory

The actual factory to use for generating the list can be set as a keyword argument, if another type (tuple, set, …) is required.

Maybe

class factory.Maybe(decider, yes_declaration, no_declaration)[source]

Sometimes, the way to build a given field depends on the value of another, for instance of a parameter.

In those cases, use the Maybe declaration: it takes the name of a “decider” boolean field, and two declarations; depending on the value of the field whose name is held in the ‘decider’ parameter, it will apply the effects of one or the other declaration:

class UserFactory(factory.Factory):
    class Meta:
        model = User

    is_active = True
    deactivation_date = factory.Maybe(
        'is_active',
        yes_declaration=None,
        no_declaration=factory.fuzzy.FuzzyDateTime(timezone.now() - datetime.timedelta(days=10)),
    )
>>> u = UserFactory(is_active=True)
>>> u.deactivation_date
None
>>> u = UserFactory(is_active=False)
>>> u.deactivation_date
datetime.datetime(2017, 4, 1, 23, 21, 23, tzinfo=UTC)

Note

If the condition for the decider is complex, use a LazyAttribute defined in the Params section of your factory to handle the computation.

Post-generation hooks

Some objects expect additional method calls or complex processing for proper definition. For instance, a User may need to have a related Profile, where the Profile is built from the User object.

To support this pattern, factory_boy provides the following tools:

Post-generation hooks are called in the same order they are declared in the factory class, so that functions can rely on the side effects applied by the previous post-generation hook.

Extracting parameters

All post-building hooks share a common base for picking parameters from the set of attributes passed to the Factory.

For instance, a PostGeneration hook is declared as post:

class SomeFactory(factory.Factory):
    class Meta:
        model = SomeObject

    @post_generation
    def post(obj, create, extracted, **kwargs):
        obj.set_origin(create)

When calling the factory, some arguments will be extracted for this method:

  • If a post argument is passed, it will be passed as the extracted field

  • Any argument starting with post__XYZ will be extracted, its post__ prefix removed, and added to the kwargs passed to the post-generation hook.

Extracted arguments won’t be passed to the model class.

Thus, in the following call:

>>> SomeFactory(
    post=1,
    post_x=2,
    post__y=3,
    post__z__t=42,
)

The post hook will receive 1 as extracted and {'y': 3, 'z__t': 42} as keyword arguments; {'post_x': 2} will be passed to SomeFactory._meta.model.

RelatedFactory

class factory.RelatedFactory(factory, factory_related_name='', **kwargs)[source]

A RelatedFactory behaves mostly like a SubFactory, with the main difference that the related Factory will be generated after the base Factory.

factory

As for SubFactory, the factory argument can be:

If set, the object generated by the factory declaring the RelatedFactory is passed as keyword argument to the related factory.

class CityFactory(factory.Factory):
    class Meta:
        model = City

    capital_of = None
    name = "Toronto"

class CountryFactory(factory.Factory):
    class Meta:
        model = Country

    lang = 'fr'
    capital_city = factory.RelatedFactory(
        CityFactory,  # Not CityFactory()
        factory_related_name='capital_of',
        name="Paris",
    )
>>> france = CountryFactory()
>>> City.objects.get(capital_of=france)
<City: Paris>

Extra kwargs may be passed to the related factory, through the usual ATTR__SUBATTR syntax:

>>> england = CountryFactory(lang='en', capital_city__name="London")
>>> City.objects.get(capital_of=england)
<City: London>

If a value is passed for the RelatedFactory attribute, this disables RelatedFactory generation:

>>> france = CountryFactory()
>>> paris = City.objects.get()
>>> paris
<City: Paris>
>>> reunion = CountryFactory(capital_city=paris)
>>> City.objects.count()  # No new capital_city generated
1
>>> guyane = CountryFactory(capital_city=paris, capital_city__name='Kourou')
>>> City.objects.count()  # No new capital_city generated, ``name`` ignored.
1

Note

The target of the RelatedFactory is evaluated after the initial factory has been instantiated. However, the build context is passed down to that factory; this means that calls to factory.SelfAttribute can go back to the calling factory’s context:

class CountryFactory(factory.Factory):
    class Meta:
        model = Country

    lang = 'fr'
    capital_city = factory.RelatedFactory(
        CityFactory,
        factory_related_name='capital_of',
        # Would also work with SelfAttribute('capital_of.lang')
        main_lang=factory.SelfAttribute('..lang'),
    )

RelatedFactoryList

class factory.RelatedFactoryList(factory, factory_related_name='', size=2, **kwargs)[source]

A RelatedFactoryList behaves like a RelatedFactory, only it returns a list of factories. This is useful for simulating one-to-many relations, rather than the one-to-one relation generated by RelatedFactory.

factory

As for SubFactory, the factory argument can be:

If set, the object generated by the factory declaring the RelatedFactory is passed as keyword argument to the related factory.

size

Either an int, or a lambda that returns an int, which will define the number of related Factories to be generated for each parent object.

New in version 2.12: Note that the API for RelatedFactoryList is considered experimental, and might change in a future version for increased consistency with other declarations.

Note

Note that using a lambda for size allows the number of related objects per parents object to vary. This is useful for testing, when you likely don’t want your mock data to have parent objects with the exact same, static number of related objects.

class FooFactory(factory.Factory):
    class Meta:
        model = Foo
    # Generate a list of `factory` objects of random size, ranging from 1 -> 5
    bar = factory.RelatedFactoryList(BarFactory, size=lambda: random.randint(1, 5))
    # Each Foo object will have exactly 3 Bar objects generated for its foobar attribute.
    foobar = factory.RelatedFactoryList(BarFactory, size=3)

PostGeneration

class factory.PostGeneration(callable)[source]

The PostGeneration declaration performs actions once the model object has been generated.

Its sole argument is a callable, that will be called once the base object has been generated.

Once the base object has been generated, the provided callable will be called as callable(obj, create, extracted, **kwargs), where:

  • obj is the base object previously generated

  • create is a boolean indicating which strategy was used

  • extracted is None unless a value was passed in for the PostGeneration declaration at Factory declaration time

  • kwargs are any extra parameters passed as attr__key=value when calling the Factory:

class UserFactory(factory.Factory):
    class Meta:
        model = User

    login = 'john'
    make_mbox = factory.PostGeneration(
            lambda obj, create, extracted, **kwargs: os.makedirs(obj.login))

Decorator

factory.post_generation()[source]

A decorator is also provided, decorating a single method accepting the same obj, create, extracted and keyword arguments as PostGeneration.

class UserFactory(factory.Factory):
    class Meta:
        model = User

    login = 'john'

    @factory.post_generation
    def mbox(obj, create, extracted, **kwargs):
        if not create:
            return
        path = extracted or os.path.join('/tmp/mbox/', obj.login)
        os.path.makedirs(path)
>>> UserFactory.build()                  # Nothing was created
>>> UserFactory.create()                 # Creates dir /tmp/mbox/john
>>> UserFactory.create(login='jack')     # Creates dir /tmp/mbox/jack
>>> UserFactory.create(mbox='/tmp/alt')  # Creates dir /tmp/alt

PostGenerationMethodCall

class factory.PostGenerationMethodCall(method_name, *arg, **kwargs)[source]

The PostGenerationMethodCall declaration will call a method on the generated object just after instantiation. This declaration class provides a friendly means of generating attributes of a factory instance during initialization. The declaration is created using the following arguments:

method_name

The name of the method to call on the model object

arg

The default, optional, positional argument to pass to the method given in method_name

kwargs

The default set of keyword arguments to pass to the method given in method_name

Once the factory instance has been generated, the method specified in method_name will be called on the generated object with any arguments specified in the PostGenerationMethodCall declaration, by default.

For example, we could use PostGenerationMethodCall to register created users in an external system.

class User(models.Model):
    name = models.CharField(max_length=191)

    def register(self, system, auth_token="ABC"):
        self.registration_id = system.register(auth_token)


class UserFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = User

    name = 'user'
    register = factory.PostGenerationMethodCall("register", DefaultRegistry())

If the PostGenerationMethodCall declaration contained no arguments or one argument, an overriding value can be passed directly to the method through a keyword argument matching the attribute name.

>>> # DefaultRegistry uses UUID for identifiers.
>>> UserFactory().registration_id
'edf42c11-0065-43ad-ad3d-78ab7497aaae'
>>> # OtherRegistry uses int for identifiers.
>>> UserFactory(register=OtherRegistry()).registration_id
123456

Warning

In order to keep a consistent and simple API, a PostGenerationMethodCall allows at most one positional argument; all other parameters should be passed as keyword arguments.

Keywords extracted from the factory arguments are merged into the defaults present in the PostGenerationMethodCall declaration.

>>> # Calls user.register(DefaultRegistry(), auth_token="DEF")
>>> UserFactory(register__auth_token="DEF")

Module-level functions

Beyond the Factory class and the various Declarations classes and methods, factory_boy exposes a few module-level functions, mostly useful for lightweight factory generation.

Lightweight factory declaration

factory.make_factory(klass, **kwargs)[source]

The make_factory() function takes a class, declarations as keyword arguments, and generates a new Factory for that class accordingly:

UserFactory = make_factory(User,
    login='john',
    email=factory.LazyAttribute(lambda u: '%s@example.com' % u.login),
)

# This is equivalent to:

class UserFactory(factory.Factory):
    class Meta:
        model = User

    login = 'john'
    email = factory.LazyAttribute(lambda u: '%s@example.com' % u.login)

An alternate base class to Factory can be specified in the FACTORY_CLASS argument:

UserFactory = make_factory(models.User,
    login='john',
    email=factory.LazyAttribute(lambda u: '%s@example.com' % u.login),
    FACTORY_CLASS=factory.django.DjangoModelFactory,
)

# This is equivalent to:

class UserFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.User

    login = 'john'
    email = factory.LazyAttribute(lambda u: '%s@example.com' % u.login)

New in version 2.0.0: The FACTORY_CLASS kwarg was added in 2.0.0.

Instance building

The factory module provides a bunch of shortcuts for creating a factory and extracting instances from them. Helper methods can be used to create factories in a dynamic way based on parameters.

Internally, helper methods use make_factory() to create a new Factory and perform additional calls on the newly created Factory according to the method name.

Please note, that all Factories created with this methods inherit from the factory.base.Factory class. For full support of your ORM, specify a base class with the FACTORY_CLASS parameter as shown in make_factory() examples.

factory.build(klass, FACTORY_CLASS=None, **kwargs)[source]
factory.build_batch(klass, size, FACTORY_CLASS=None, **kwargs)[source]

Create a factory for klass using declarations passed in kwargs; return an instance built from that factory with BUILD_STRATEGY, or a list of size instances (for build_batch()).

Parameters:
  • klass (class) – Class of the instance to build

  • size (int) – Number of instances to build

  • kwargs – Declarations to use for the generated factory

  • FACTORY_CLASS – Alternate base class (instead of Factory)

factory.create(klass, FACTORY_CLASS=None, **kwargs)[source]
factory.create_batch(klass, size, FACTORY_CLASS=None, **kwargs)[source]

Create a factory for klass using declarations passed in kwargs; return an instance created from that factory with CREATE_STRATEGY, or a list of size instances (for create_batch()).

Parameters:
  • klass (class) – Class of the instance to create

  • size (int) – Number of instances to create

  • kwargs – Declarations to use for the generated factory

  • FACTORY_CLASS – Alternate base class (instead of Factory)

factory.stub(klass, FACTORY_CLASS=None, **kwargs)[source]
factory.stub_batch(klass, size, FACTORY_CLASS=None, **kwargs)[source]

Create a factory for klass using declarations passed in kwargs; return an instance stubbed from that factory with STUB_STRATEGY, or a list of size instances (for stub_batch()).

Parameters:
  • klass (class) – Class of the instance to stub

  • size (int) – Number of instances to stub

  • kwargs – Declarations to use for the generated factory

  • FACTORY_CLASS – Alternate base class (instead of Factory)

factory.generate(klass, strategy, FACTORY_CLASS=None, **kwargs)[source]
factory.generate_batch(klass, strategy, size, FACTORY_CLASS=None, **kwargs)[source]

Create a factory for klass using declarations passed in kwargs; return an instance generated from that factory with the strategy strategy, or a list of size instances (for generate_batch()).

Parameters:
  • klass (class) – Class of the instance to generate

  • strategy (str) – The strategy to use

  • size (int) – Number of instances to generate

  • kwargs – Declarations to use for the generated factory

  • FACTORY_CLASS – Alternate base class (instead of Factory)

factory.simple_generate(klass, create, FACTORY_CLASS=None, **kwargs)[source]
factory.simple_generate_batch(klass, create, size, FACTORY_CLASS=None, **kwargs)[source]

Create a factory for klass using declarations passed in kwargs; return an instance generated from that factory according to the create flag, or a list of size instances (for simple_generate_batch()).

Parameters:
  • klass (class) – Class of the instance to generate

  • create (bool) – Whether to build (False) or create (True) instances

  • size (int) – Number of instances to generate

  • kwargs – Declarations to use for the generated factory

  • FACTORY_CLASS – Alternate base class (instead of Factory)

Randomness management

Using random in factories allows to “fuzz” a program efficiently. However, it’s sometimes required to reproduce a failing test.

factory.fuzzy and factory.Faker share a dedicated instance of random.Random, which can be managed through the factory.random module:

factory.random.get_random_state()[source]

Call get_random_state() to retrieve the random generator’s current state. This method synchronizes both Faker’s and factory_boy’s random state. The returned object is implementation-specific.

factory.random.set_random_state(state)[source]

Use set_random_state() to set a custom state into the random generator (fetched from get_random_state() in a previous run, for instance)

factory.random.reseed_random(seed)[source]

The reseed_random() function allows to load a chosen seed into the random generator. That seed can be anything accepted by random.seed().

See Using reproducible randomness for help in using those methods in a test setup.