In factory-boy I'm using a trait to create an optional related object.
class WarehouseToCustomerFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta:
model = WarehouseToCustomer
exclude = ["billing_profile"]
account = factory.SubFactory(AccountFactory, billing_plan=Account.THREEPL_BILLING_PLAN)
warehouse_accepted = True
customer_accepted = True
class Params:
with_billing_profile = factory.Trait(
billing_profile = factory.SubFactory(
"factories.billing_profile.BillingProfileFactory",
account=factory.SelfAttribute("..account"),
name="Small Customer"
),
billing_profile_id = factory.SelfAttribute("billing_profile.id")
)
So I can create my object without a "billing_profile" by default, but if I explicitly enable the trait, it's created.
>>> WarehouseToCustomerFactory(with_billing_profile=True)
Overriding attributes if the trait is on also works,
>>> WarehouseToCustomerFactory(with_billing_profile=True, billing_profile__name="Medium Customer")
But is it possible to assume with_billing_profile=True if I'm explicitly overriding billing_profile or any of its attributes? For example...
>>> WarehouseToCustomerFactory(billing_profile=a_profile_instance)
>>> WarehouseToCustomerFactory(billing_profile__name="A custom profile")