model_bakery icon indicating copy to clipboard operation
model_bakery copied to clipboard

Add field lookup syntax to `_fill_optional`

Open berinhard opened this issue 5 years ago • 3 comments

I'll base my feature request using the following models as examples:

class FkModel(models.Model):
    not_optional = models.CharField(max_length=500)
    optional = models.CharField(max_length=500)

class MainModel(models.Model):
    optional_fk = models.ForeignKey(
        FKModel, null=True, blank=True, on_delete=models.SET_NULL
    )

Now, let's imagine we have a test scenario for my MainModel which depends on the optional field from a optional_fk to have some random value so the test can pass.

Model mommy already solves this test setup scenario, but I think we could also be able to do so via _fill_optional with lookup fields. In my opinion, this would increase model mommy's API because we already can use lookup fields to create or prepare instances and recipes.

Expected behavior

My suggestions is to add the lookup feature also to the _fill_optional value. So, the following call would be valid:

obj = mommy.make(MainModel, _fill_optional=['optional_fk__optional'])
assert bool(obj.optional_fk.optional) is True

Actual behavior

Right now, model_mommy force us to manually create an instance of FKModel with the optional fields being populated and then to pass is to mommy.make when creating a new instance of MainModel. Here's how we have to code the same test scenario today:

optional_obj = mommy.make(FKModel, _fill_optional=['optional'])
obj = mommy.make(MainModel, optional_fk=optional_obj)
assert bool(obj.optional_fk.optional) is True

berinhard avatar May 06 '19 15:05 berinhard

_fill_optional is not filling the optional fields of a related model(foreign key, onetoone, etc). Shouldn't it populate them also?

class Book(models.Model):
    name = models.CharField(max_length=100)
    author = models.ForeignKey(Author, on_delete=models.SET_NULL, null=True, blank=True)

class Author(models.Model):
    name = models.CharField(max_length=100)
    address = models.CharField(null=True, blank=True)

book = baker.bake(Book, _fill_optional=True)
assert book.author.address != ''

The last statement will fail as it is not filling optional fields on the related model.

ChillarAnand avatar Dec 14 '19 07:12 ChillarAnand

I'm a +1 for that @ChillarAnand. Your comment is totally related to this issue, thanks for bringing it up.

berinhard avatar Dec 16 '19 15:12 berinhard

+1 to both of these requests. I would have expected _fill_optional=True to cascade to related models.

JustinC474 avatar Jan 16 '21 18:01 JustinC474