Why does the naming of RelatedFactory variables in factory-boy affect when the factories are executed/instantiated?
Asked Answered
C

0

3

When I named my RelatedFactory variables pv_something, the factories wouldn't be run until after the post_generation method. When I renamed the variables to param_val_something they would be run before the post_generation method.

In the following code, RelatedFactory is not run until after post_generation, so self.something_set.all() is empty, and the line t.something_else = 'abc' is never executed.

class ThingFactory(factory.DjangoModelFactory):
    class Meta:
        model = Thing

    name = 'a thing'

    pv_something = factory.RelatedFactory(SomethingFactory, 'thing')

    @factory.post_generation
    def post(self, create, extracted, **kwargs):
        for t in self.something_set.all():
            t.something_else = 'abc'

In the following code, the only difference is renaming the variable pv_something to param_val_something. Now, self.something_set.all() is not empty, and the line t.something_else = 'abc' is executed.

class ThingFactory(factory.DjangoModelFactory):
    class Meta:
        model = Thing

    name = 'a thing'

    param_val_something = factory.RelatedFactory(SomethingFactory, 'thing')

    @factory.post_generation
    def post(self, create, extracted, **kwargs):
        for t in self.something_set.all():
            t.something_else = 'abc'

I'm using Python 3.4.3, Django 1.8.5, and factory-boy 2.5.2.

Midnight Friday night, this nearly sent me over the edge..

Caprifoliaceous answered 30/10, 2015 at 20:49 Comment(2)
I briefly wondered if the issue was population of the self.something_set list, but Something.objects.filter(thing_id=self.id) also failed to retrieve the RelatedFactory records.Caprifoliaceous
Ridiculous as it sounds I am 100% certain the naming was all that changed to fix it. Now, randomly, the RelatedFactory calls are being called after post-gen again, with the 'fixed' variable names. My lazy solution was to move the factory.RelatedFactory(SomethingFactory, 'thing') calls into the post-gen method as pv_something = SomethingFactory(thing=self). The order of RelatedFactory and post-gen doesn't seem to be guaranteed - presumably a consequence of some lazy evaluation somewhere.Caprifoliaceous

© 2022 - 2024 — McMap. All rights reserved.