factory_boy icon indicating copy to clipboard operation
factory_boy copied to clipboard

Related factory overriding

Open ihorm5 opened this issue 1 year ago • 0 comments

I recently updated my project from Django 3.2 to Django 5.0. One particular issue I encountered was related to factory_boy. Here’s what happened:

The Problem

I had the following factory definition:

class MemberFactory(BaseFactory):
    class Meta:
        model = User
        django_get_or_create = ('email',)

    gov_id_verification = factory.RelatedFactory('api.tests.factories.GovernmentIDVerificationFactory', 'user')

In previous versions, I could easily override gov_id_verification in a subclassed factory like this:

class MemberFactory2(MemberFactory):
    gov_id_verification = None

But during the update, this started raising an error: ValueError: The following fields do not exist in this model: gov_id_verification.

The Solution I Used

To resolve this, I ended up using a post_generation method to control whether the related factory should be created or not. Here’s the solution I used:

@factory.post_generation
def gov_id_verification(self, create, extracted, **kwargs):
    # Override gov_id_verification to skip its creation in MemberFactory2
    if create and extracted is not False:
        # Create a new government ID verification only if explicitly requested
        GovernmentIDVerificationFactory(user=self, **(extracted or {}))

Question

Is there an easier way to handle such cases where I want to make related factories optional in a clean and straightforward manner?

I’d appreciate any suggestions or tips on simplifying this process.

ihorm5 avatar Nov 06 '24 08:11 ihorm5