I'm building a factory with factory_boy
that generates a django model. I would like to see what arguments the user inputs inline. My factory itself looks like this
class SomeFactory(factory.django.DjangoModelFactory):
name = factory.Sequence(lambda n: 'Instance #{}'.format(n))
some_other_thing = factory.SubFactory(SomeOtherFactory)
class Meta:
model = SomeModel
Now the user could say s = SomeFactory()
and it would work fine, but I want to detect if the user input their own argument. For instance, to tell if the user passed in their own name, as in s = SomeFactory(name='Matt')
What I've tried so far is
__init__
function in the SomeFactory
class
s = SomeFactory()
, nor when I call s.__init__()
__new__
method_adjust_kwargs
kwargs
, not just the ones the user defined. For instance, calling s = SomeFactory(name='Matt')
, I would get a kwargs
dict with keys for name
and some_other_thing
, which makes it impossible to tell input their own argument or not_create
_adjust_kwargs
, in that kwargs
doesn't contain the original kwargs
, but rather all of the argumentsI think a lot of the functionality I'm after is black-boxed inside of factory_boy
's StepBuilder
(I suspect it's in the instantiate
method) but I have no idea how to modify it to do what I want.
Does anyone have any thoughts on how to figure out which kwargs
were set originally in the call to s = SomeFactory()
? I.e. determine that if I said s = SomeFactory(name='Matt')
, that the user manually set the name?
Thanks!
Update: I'm running django
version 1.11.2
, factory_boy
version 2.8.1
, and python
version 3.5.2
You can override the create
method to only get the user kwargs.
A full example would be something like this:
from django.contrib.auth.models import User
import factory
class UserFactory(factory.DjangoModelFactory):
username = factory.Sequence(
lambda n: 'test'
)
email = factory.Sequence(lambda n: 'user{0}@example.com'.format(n))
class Meta:
model = User
@classmethod
def create(cls, **kwargs):
# here you'll only have the kwargs that were entered manually
print(str(kwargs))
return super(UserFactory, cls).create(**kwargs)
So when I call it:
In [2]: UserFactory(username='foobar')
{'username': 'foobar'}
Out[2]: <User: foobar>
If you want to catch kwargs for other build strategies than create
, you would also need to do this for the stub
and build
method.
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