model-bakers / model_bakery

Object factory for Django
https://model-bakery.readthedocs.io/en/latest/
Other
846 stars 85 forks source link

How do I deal with complex relationships? #427

Open boatcoder opened 1 year ago

boatcoder commented 1 year ago
class Campaign()
    product = models.foreignkey('app.product', null=False)
    ...

class Offer()
    price = models.foreignkey('app.price', null=False)
    ....

class Price()
    product = models.foreignkey('app.product', null=False)
    ....

How do I write a recipe for Offer that will use the same product for both Campaign and for Price? I don't think related covers this. And when I try to spec it out using attrs, I run into issues of campaign__product=something so I need it to be smart enough to find the first product specified and then create the non-specified product to the same thing as the one that was specified.

An example:

make_recipie("offer", price=Foo). campaign will be created with product = Foo.price make_recipe("offer", campaign=Camp1). price will be created withprice = make_recipe('price', product=Camp1.product)`

I don't think any of this is possible with model bakery because there is no way to express the relationship between different parts and the constituent pieces are created separately and then assembled into a unit. This almost seems like it needs a graph where relationships like the above can be specified and then built grabbing parts that are still missing.

Another way it could maybe be done is using ordered dicts and tuples to apply missing params

In which case:

Offer Recipe
   campaign = foreign_key('campaign')
   price = foreign_key('price', product=campaign__product)

but foreign_key only takes 2 arguments and there is no way to specified the order of the pieces being created (because of iteration over a dict)

However the above does not deal with price=anything being used in the campaign unless it was specified as campaign__price__product=anything.product. So maybe the only way do this correctly is to build a graph and connect the dots but then I need a way to specify that graph. Currently the only way to do it is to "bake" things in the correct order and build the composite object from pieces