Cookiecutter is a command line utility which constructs code from a set of Jinja2 templates. It can use these templates directly from a Github repository as well, prompting for configuration values as needed. It's fairly simple, but I can see it becoming one of those indispensable tools.

I've been playing around with using it to automate Django app creation with loads of the common boilerplate that I'd often end up doing. Currently it creates an app based around a model with:

  • CRUD views provided by django-vanilla-views.
  • A factory for the new model using FactoryBoy.
  • Tests for each of the views using WebTest.
  • A Django ModelForm using floppyforms.
  • Default templates for the views.

It was fairly straightforward, but with a few minor things worth noting:

1 - When creating Django templates which include any tags you need to wrap the entire template in {% raw %} tags so that Jinja2 doesn't try and parse it. You then, however, need to turn parsing back on for any situation where you do want something parsed by cookiecutter/Jinja, like a cookiecutter variable. This can lead to some confusing looking syntax, for example:

{% raw %}
<a href="{% url '{% endraw %}{{ cookiecutter.model_name|lower }}{% raw %}_update' object.pk %}">Update</a>
{% endraw %}

Just the parts between the {% endraw %}..{% raw %} are parsed by Jinja - the rest we want to be viewed as regular text intil it finds itself in the Django project being run.

2 - The current release of cookiecutter on PyPy (0.6.4) wanted me to have a repo_name key in my JSON config for it to work directly from Github. If I switched to using the dev version it's fine, so I'll use that until 0.7 lands.

cookiecutter 0.7 is now on PyPI so you can use the stable version.

3 - Cookiecutter will overwrite generated files without warning, so make sure you have your code checked in before playing around with it and accidentally generating things over an existing app.

The template I built is over on github. If you want to use it in your project, first, install cookiecutter, along with the packages required to run the bits in the generated Django project (django-vanilla-views, webtest, floppyforms). These are all in a requirements file, so you can just do:

pip install -r https://raw.github.com/wildfish/cookiecutter-django-crud/master/requirements.txt

Run cookiecutter, armed with this template. Follow the prompts for the app_name and model_name you'd like to use. The app will be created as <app_name> under the current directory. Don't forget me saying that it will overwrite existing files without warning you if you already have an app of the same name, so make sure your code is checked in or backed up.

cookiecutter git@github.com:wildfish/cookiecutter-django-crud.git

Add the newly generated app, and floppyforms, to INSTALLED_APPS in your settings.py:

INSTALLED_APPS = (
    ..
    'floppyforms',
    'yourproject.things',
)
  1. Hook up the urls for the new app by adding something like the following to your root urls.py:
url(r'^things/', include('yourproject.things.urls')),
  1. Run your freshly generated tests to check that all of the previous steps have worked:
python manage.py test yourproject.things
  1. Edit the models.py for the new app with the fields you'd like to use.
  2. Syncdb to set up your new model in the DB.
python manage.py syncdb
  1. Run a dev server if it's not running already, and browse to http://localhost:8000/things/ and marvel at your new CRUD app.

If you already have a base.html template you'll need to ensure there's a Django content block named "content" for anything to show up. There's a default base.html included otherwise.

You'll probably want to fork my templates and create your own however you like your Django projects set up, but any pull requests for things which may be useful more generally would be welcome as well.

Rolo.

blog comments powered by Disqus