Search code examples
djangofactory-boy

When is _create() method of factory.DjangoModelFactory called when initialising an object?


We are using factoryboy and following the docs seem to do the task intended but am trying to understand what goes behind the screens.

We are overwriting _create() method of factory.DjangoModelFactory for custom user creation. However there is no init in the class. How does python ensure that _create() method is called every time a factory object is created?

class CustomerFactory(factory.DjangoModelFactory):

      class Meta:
            model = Customer

      @class_method
       def _create(cls, model_class, *args, **kwargs):
           ...... <custom_code>

alex = CustomerFactory()

Solution

  • Factory boy uses a metaclass to achieve this result.

    Basically, the metaclass (factory.base.FactoryMetaClass) receives the class definition from your code, and transforms it — just like Django does with its models. This happens inside FactoryMetaClass.__new__.

    The metaclass also provides a custom __call__ method, which is used by Python when you run CustomerFactory().

    The call order is then:

    1. Your code calls CustomerFactory()
    2. Python actually runs FactoryMetaClass.__call__(CustomerFactory)
    3. That function calls CustomerFactory.create() (since it's a DjangoModelFactory; other factories route the default call to MyFactory.build())
    4. FactoryBoy's core engine resolves parameters and declarations
    5. And provides the resulting list of parameters to CustomerFactory._create(**params)
    6. Where your code takes over.