fcurella / django-fakery

🏭 An easy-to-use implementation of Creation Methods for Django, backed by Faker.
http://django-fakery.readthedocs.org/en/stable/
MIT License
115 stars 6 forks source link

Consider making Blueprint.fields() update fields instead of overwriting #50

Closed jacobian closed 5 years ago

jacobian commented 5 years ago

I think Blueprint.fields() should return a new Blueprint, with updated fields, instead of overwriting all existing fields. This makes for what I think is a more intuitive API when using blueprints.

I'm happy to work up a PR for this if the direction seems appropriate, but I want to validate the direction before I code it up.

Steps to reproduce

I have a blueprint:

reports = factory.blueprint(Report).fields(
    contract_number=lambda n, f: f.bothify("K#####T####"),
    ... many more fields ...
)

This model happens to have a FK to another model (Contractor) , so I tried something that seemed intuitive:

c = contractors.make()
r = reports.fields(contractor=c).make()

This feels like a fairly intuitive API for making "sub-blueprints", but it doesn't work.

Expected behavior

I expected the fields on r to be set according to my field callbacks.

Actual behavior

Instead, not only are the field callbacks not called, subsequent calls to the the report blueprint don't get it either! This is because Blueprint.fields overwrites self._fields


If Blueprint.fields was instead something like:

def fields(self, **kwargs):
    new_fields = self._fields.copy()
    new_fields.update(kwargs)
    return Blueprint(self.model, new_fields, pre_save=self.pre_save, post_save=self.post_save, seed=self.seed)

Then what I expected to happen, would in fact happen. Again I think this makes for a more natural, easy-to-use API -- but maybe I'm wrong? LMK if you'd like to see a patch!

fcurella commented 5 years ago

Hi @jacobian ,

I actually think the current behavior is a bug. The README doesn't mention overwriting at all, and the use-case it shows seems to imply updating.

Go ahead and submit a PR if you can! Thank you so much!