Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SubFactory with a None value by default #900

Closed
aleehedl opened this issue Jan 3, 2022 · 2 comments
Closed

SubFactory with a None value by default #900

aleehedl opened this issue Jan 3, 2022 · 2 comments
Labels

Comments

@aleehedl
Copy link

aleehedl commented Jan 3, 2022

The problem

Occasionally I want to have a SubFactory (or a RelatedFactory) whose value is set to None unless explicitly stated. That is, I would want to FooFactory().bar to be None but still be able to use FooFactory(bar__name='test) or FooFactory(bar=BarFactory()).

class BarFactory(DjangoModelFactory):
    name = factory.Faker("first_name")

class FooFactory(DjangoModelFactory):
    bar = factory.SubFactory(BarFactory)

Is this achievable somehow? Obviously I could use FooFactory(bar=None) but this is not ideal.

@aleehedl aleehedl changed the title RelatedFactory with a None value by default SubFactory with a None value by default Jan 3, 2022
@rbarrois
Copy link
Member

rbarrois commented Jan 3, 2022

It's quite hard to support directly: in the current engine, declarations will be grouped by their "root", e.g all declarations starting with bar__ are considered to be parameters for the bar= declaration.

If the default is bar=None, any value provided to bar__name would either cause a failure or be ignored.

The simplest option would be to use a factory.Trait:

class FooFactory(factory.Factory):
  class Params:
    with_bar = factory.Trait(bar=factory.SubFactory(BarFactory))

With that, you could use:

>>> FooFactory()  # Nothing requested
<Foo, bar=None>
>>> FooFactory(with_bar=True)  # Default call to `BarFactory`
<Foo, bar=<Bar, name="John">>
>>> FooFactory(with_bar=True, bar__name="test")  # Include `bar=`, and provide a value
<Foo, bar=<Bar, name="test">>
>>> FooFactory(bar__name="test")  # Slightly weird behaviour: the `BarFactory` is fully ignored.
<Foo, bar=None>

I hope this helps?

@rbarrois rbarrois added the Q&A label Jan 3, 2022
@aleehedl
Copy link
Author

aleehedl commented Jan 4, 2022

Thanks for the reply. Traits will have to suffice :-)

@aleehedl aleehedl closed this as completed Jan 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants