Package: django-fakery
An easy-to-use implementation ofCreation Methods(aka Object Factory) for Django, backed byFaker.django_fakerywill try to guess the field’s value based on the field’s name and type.InstallationInstall with:$ pip install django-fakeryQuickStartfromdjango_fakeryimportfactoryfrommyapp.modelsimportMyModelfactory.m(MyModel)(field='value')If you’re having issues with circular imports, you can also reference a model by using theMutility function:fromdjango_fakeryimportfactory,Mfactory.m(M("myapp.MyModel"))(field="value")If you really don’t want to import things, you could also just reference a model by using the<app_label>.<ModelName>syntax. This is not encouraged, as it will likely break type-hinting:fromdjango_fakeryimportfactoryfactory.m("myapp.MyModel")(field="value")If you usepytest, you can use thefakeryandfakery_shortcuts` fixtures (requires ``pytestandpytest-django):importpytestfrommyapp.modelsimportMyModel@pytest.mark.django_dbdeftest_mymodel(fakery,fakery_shortcuts):fakery.m(MyModel)(field=fakery_shortcuts.future_datetime())If you’d rather, you can use a more wordy API:fromdjango_fakeryimportfactoryfrommyapp.modelsimportMyModelfactory.make(MyModel,fields={'field':'value',})We will use the short API thorough the documentation.The value of a field can be any python object, a callable, or a lambda:fromdjango.utilsimporttimezonefromdjango_fakeryimportfactoryfrommyapp.modelsimportMyModelfactory.m(MyModel)(created=timezone.now)When using a lambda, it will receive two arguments:nis the iteration number, andfis an instance offaker:fromdjango.contrib.auth.modelsimportUseruser=factory.m(User)(username=lambdan,f:'user_{}'.format(n),)django-fakeryincludes some pre-built lambdas for common needs. Seeshortcutsfor more info.You can create multiple objects by using thequantityparameter:fromdjango_fakeryimportfactoryfromdjango.contrib.auth.modelsimportUserfactory.m(User,quantity=4)For convenience, when the value of a field is a string, it will be interpolated with the iteration number:frommyapp.modelsimportMyModeluser=factory.m(User,quantity=4)(username='user_{}',)Custom fieldsYou can add support for custom fields by adding your
custom field class and a function infactory.field_types:fromdjango_fakeryimportfactoryfrommy_fieldsimportCustomFielddeffunc(faker,field,count,*args,**kwargs):return43factory.field_types.add(CustomField,(func,[],{}))As a shortcut, you can specified any Faker function by its name:fromdjango_fakeryimportfactoryfrommy_fieldsimportCustomFieldfactory.field_types.add(CustomField,("random_int",[],{"min":0,"max":60}))Foreign keysNon-nullableForeignKeys create related objects automatically.If you want to explicitly create a related object, you can pass a factory like any other value:fromdjango.contrib.auth.modelsimportUserfromfood.modelsimportPizzapizza=factory.m(Pizza)(chef=factory.m(User)(username='Gusteau'),)If you’d rather not create related objects and reuse the same value for a foreign key, you can use the special valuedjango_fakery.rels.SELECT:fromdjango_fakeryimportfactory,relsfromfood.modelsimportPizzapizza=factory.m(Pizza,quantity=5)(chef=rels.SELECT,)django-fakerywill always use the first instance of the related model, creating one if necessary.ManyToManiesBecauseManyToManyFields are implicitly nullable (ie: they’re always allowed to have their.count()equal to0), related objects on those fields are not automatically created for you.If you want to explicitly create a related objects, you can pass a list as the field’s value:fromfood.modelsimportPizza,Toppingpizza=factory.m(Pizza)(toppings=[factory.m(Topping)(name='Anchovies')],)You can also pass a factory, to create multiple objects:fromfood.modelsimportPizza,Toppingpizza=factory.m(Pizza)(toppings=factory.m(Topping,quantity=5),)Shortcutsdjango-fakeryincludes some shortcut functions to generate commonly needed values.future_datetime(end='+30d')Returns adatetimeobject in the future (that is, 1 second from now) up to the specifiedend.endcan be a string, anotther datetime, or a timedelta. If it’s a string, it must start with+, followed by and integer and a unit, Eg:'+30d'. Defaults to'+30d'Valid units are:'years','y''weeks','w''days','d''hours','hours''minutes','m''seconds','s'Example:fromdjango_fakeryimportfactory,shortcutsfrommyapp.modelsimportMyModelfactory.m(MyModel)(field=shortcuts.future_datetime('+1w'))future_date(end='+30d')Returns adateobject in the future (that is, 1 day from now) up to the specifiedend.endcan be a string, another date, or a timedelta. If it’s a string, it must start with+, followed by and integer and a unit, Eg:'+30d'. Defaults to'+30d'past_datetime(start='-30d')Returns adatetimeobject in the past between 1 second ago and the specifiedstart.startcan be a string, another datetime, or a timedelta. If it’s a string, it must start with-, followed by and integer and a unit, Eg:'-30d'. Defaults to'-30d'past_date(start='-30d')Returns adateobject in the past between 1 day ago and the specifiedstart.startcan be a string, another date, or a timedelta. If it’s a string, it must start with-, followed by and integer and a unit, Eg:'-30d'. Defaults to'-30d'LaziesYou can refer to the created instance’s own attributes or method by usingLazyobjects.For example, if you’d like to create user with email as username, and have them always match, you could do:fromdjango_fakeryimportfactory,Lazyfromdjango.contrib.auth.modelsimportUserfactory.m(auth.User)(username=Lazy('email'),)If you want to assign a value returned by a method on the instance, you can pass the method’s arguments to theLazyobject:fromdjango_fakeryimportfactory,Lazyfrommyapp.modelsimportMyModelfactory.m(MyModel)(myfield=Lazy('model_method','argument',keyword='keyword value'),)Pre-save and Post-save hooksYou can define functions to be called right before the instance is saved or right after:fromdjango.contrib.auth.modelsimportUserfromdjango_fakeryimportfactoryfactory.m(User,pre_save=[lambdau:u.set_password('password')],)(username='username')Since settings a user’s password is such a common case, we special-cased that scenario, so you can just pass it as a field:fromdjango.contrib.auth.modelsimportUserfromdjango_fakeryimportfactoryfactory.m(User)(username='username',password='password',)Get or MakeYou can check for existance of a model instance and create it if necessary by using theg_m(short forget_or_make) method:frommyapp.modelsimportMyModelmyinstance,created=factory.g_m(MyModel,lookup={'myfield':'myvalue',})(myotherfield='somevalue')If you’re looking for a more explicit API, you can use the.get_or_make()method:frommyapp.modelsimportMyModelmyinstance,created=factory.get_or_make(MyModel,lookup={'myfield':'myvalue',},fields={'myotherfield':'somevalue',},)Get or UpdateYou can check for existence of a model instance and update it by using theg_u(short forget_or_update) method:frommyapp.modelsimportMyModelmyinstance,created=factory.g_u(MyModel,lookup={'myfield':'myvalue',})(myotherfield='somevalue')If you’re looking for a more explicit API, you can use the.get_or_update()method:frommyapp.modelsimportMyModelmyinstance,created=factory.get_or_update(MyModel,lookup={'myfield':'myvalue',},fields={'myotherfield':'somevalue',},)Non-persistent instancesYou can build instances that are not saved to the database by using the.b()method, just like you’d use.m():fromdjango_fakeryimportfactoryfrommyapp.modelsimportMyModelfactory.b(MyModel)(field='value',)Note that since the instance is not saved to the database,.build()does not support ManyToManies or post-save hooks.If you’re looking for a more explicit API, you can use the.build()method:fromdjango_fakeryimportfactoryfrommyapp.modelsimportMyModelfactory.build(MyModel,fields={'field':'value',})BlueprintsUse a blueprint:fromdjango.contrib.auth.modelsimportUserfromdjango_fakeryimportfactoryuser=factory.blueprint(User)user.make(quantity=10)Blueprints can refer other blueprints:fromfood.modelsimportPizzapizza=factory.blueprint(Pizza).fields(chef=user,))You can also override the field values you previously specified:fromfood.modelsimportPizzapizza=factory.blueprint(Pizza).fields(chef=user,thickness=1))pizza.m(quantity=10)(thickness=2)Or, if you’d rather use the explicit api:fromfood.modelsimportPizzapizza=factory.blueprint(Pizza).fields(chef=user,thickness=1))thicker_pizza=pizza.fields(thickness=2)thicker_pizza.make(quantity=10)Seeding the fakerfromdjango.contrib.auth.modelsimportUserfromdjango_fakeryimportfactoryfactory.m(User,seed=1234,quantity=4)(username='regularuser_{}')CreditsThe API is heavily inspired bymodel_mommy.LicenseThis software is released under the MIT License.