django-factories provides a convenient way to generate model instances for use in your tests. It is inspired by the Ruby project factory_girl.
This project is not yet available on PyPI. For now you can try it out by cloning it from github:
$ git clone git://github.com/mirhampt/django-factories.git $ cd django-factories $ python setup.py install
First, you need to create a subclass of Factory
and define some blueprints.
Blueprints define the default values for the models generated by the factory
class. A blueprint method should return a dict and use the blueprint
decorator. Here is a simple example for a fictional blog
app:
from factories import Factory, blueprint class BlogFactory(Factory): "Factory for blog application." @blueprint(model='blog.Post') def post(self): "A simple public blog post." return { 'title': 'Blog Post', 'content': "Sorry I haven't posted in a while...", 'is_public': True, } @blueprint(model='blog.Post') def private_post(self): "A private blog post." post = self.post() post['is_public'] = False return post @blueprint(model='blog.Author') def author(self): "A blog author." return { 'first_names': 'John', 'last_name': 'Doe', 'email': '%(first_names)s_%(last_name)s@somewhere', }
For each blueprint, two methods will be created based on the name of the blueprint:
- build_<blueprint_name>
- This method will create an instance of the model passed to the
blueprint
decorator using the defaults provided by the blueprint. Any keyword arguments passed to this method will be used to override the default blueprint data. - create_<blueprint_name>
- This method acts the same as the build method described above, but saves the model instance to the database before returning it.
If your blueprint is named default
, the factory will also have a
build()
and create()
method, which are aliases for
build_default()
and create_default()
.
Now, we can create an instance of BlogFactory
and start generating test
data:
>>> blog_factory = BlogFactory() >>> public_post = blog_factory.build_post() >>> public_post.title 'Blog Post' >>> public_post.content "Sorry I haven't posted in a while..." >>> public_post.is_public True >>> public_post.pk is None # The post was not saved to the database. True # The create_post method also saves the instance to the database. >>> saved_post = blog_factory.create_post() >>> saved_post.pk is None False >>> private_post = blog_factory.build_private_post() >>> private_post.title 'Blog Post' >>> private_post.content "Sorry I haven't posted in a while..." >>> private_post.is_public False
Individual defaults provided by the blueprint can be overridden:
>>> new_post = blog_factory.build_post(title='Brand new post') >>> new_post.title 'Brand new post'
If any of the strings in the blueprint include standard Python formatting by key name syntax, the values of the other parameters will be interpolated into the string:
>>> author = blog_factory.build_author() >>> author.email 'John_Doe@somewhere' >>> sam_author = blog_factory.build_author(first_names='Sam') >>> author.email 'Sam_Doe@somewhere'
A simple factory for the flatpages
contrib app is included:
>>> from factories.flat_pages import FlatPageFactory >>> fp_factory = FlatPageFactory() >>> public_page = fp_factory.create_flat_page() >>> protected_page = fp_factory.create_protected_flat_page()
- Support associations between blueprints.
- Support numerical sequences in blueprints.
- Write more bundled factories for contrib apps: auth, sites, etc.
- Create management command to print out information about available blueprints.
- Write a tutorial.
Please report bugs via github's issue tracker.