In defining a ModelFactory in FactoryBoy, I need to access an attribute of another model created by SubFactory and assign it to this ModelFactory's attribute.
This is what I want to do:
import factory
class MyModelFactory(factory.DjangoModelFactory):
FACTORY_FOR = MyModel
created_by = factory.SubFactory(AdminUserFactory)**.id**
Obviously that doesn't work because there is no AdminUser object to access the id in the MyModelFactory class definition.
This is what I have done, but it is ugly:
import factory
class MyModelFactory(factory.DjangoModelFactory):
FACTORY_FOR = MyModel
dummy_created_by = factory.SubFactory(AdminUserFactory)
created_by = factory.LazyAttribute(lambda o: o.dummy_created_by.id)
@classmethod
def _create(cls, target_class, *args, **kwargs):
del kwargs['dummy_created_by']
return super(MyModelFactory, cls)._created(
target_class, *args, **kwargs)
I was trying to read through the Factory_Boy docs but didn't see a class or function that would allow me to lazily access the attribute. Does Anyone have any suggestions?
DjangoModelFactory is a basic interface from factory_boy that gives "ORM powers" to your factories. It's main feature here is that it provides you with a common "create" and "build" strategies that you can use to generate objects in your tests.
factory_boy is a fixtures replacement based on thoughtbot's factory_bot. As a fixtures replacement tool, it aims to replace static, hard to maintain fixtures with easy-to-use factories for complex objects.
From factoryboy 2.4.0 onwards you can use exclude. This lets you add a parameter to the factory that won't be passed onto the model class
import factory
class MyModelFactory(factory.DjangoModelFactory):
created_by = factory.SubFactory(AdminUserFactory)
created_by_id = factory.LazyAttribute(lambda o: o.created_by.id)
class Meta:
model = MyModel
exclude = ['created_by']
I've shifted the OPs example to use created_by_id
but you can rename it to make sense for you.
Use SelfAttribute:
class MyModelFactory(factory.django.DjangoModelFactory):
FACTORY_FOR = MyModel
dummy_created_by = factory.SubFactory(AdminUserFactory)
created_by = factory.SelfAttribute('dummy_created_by.id')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With