In a previous post I discussed a sensible folder layout for deploying a new Django project. Since then, Django has updated the default project layout and I've also had some time to reflect and adjust my previous layout. Let's have a look at a new and improved folder structure and layout for project using Django >= 1.5.

This post assumes that you are using virtualenv (and ideally virtualenvwrapper which I very much recommend) and Github. Furthermore, to make this concrete, we will assume that the following directory is in ~/Sites/.

So let's first have a general overview of the suggested layout:

.                                           # HOME PATH
|-- football.com                            # ENVIRONMENT PATH
|   |-- bin
|   |-- db.sql
|   |-- football.com                        # SITE PATH
|   |   |-- README.md
|   |   |-- assets
|   |   |-- bin
|   |   |-- docs
|   |   |-- etc
|   |   |-- fabfile.py
|   |   `-- src                             # PROJECT PATH
|   |       |-- app1
|   |       |   |-- __init__.py
|   |       |   |-- admin.py
|   |       |   |-- forms.py
|   |       |   |-- models.py
|   |       |   |-- tests.py
|   |       |   `-- urls.py
|   |       |-- app2
|   |       |   |-- __init__.py
|   |       |   |-- admin.py
|   |       |   |-- forms.py
|   |       |   |-- models.py
|   |       |   `-- urls.py
|   |       |-- football
|   |       |   |-- __init__.py
|   |       |   |-- settings
|   |       |   |   |-- __init__.py
|   |       |   |   |-- development.py
|   |       |   |   |-- private.py
|   |       |   |   |-- production.py
|   |       |   |   `-- settings.py
|   |       |   |-- urls.py
|   |       |   `-- wsgi.py
|   |       |-- manage.py
|   |       |-- requirements.txt
|   |       |-- static
|   |       |-- templates
|   |       `-- utils
|   |-- include
|   |-- lib
|   |-- media
|   |-- share
|   `-- static
|-- rugby.com
`-- tennis.com

Server Files

The first distinction that needs to be made when thinking about project layout is:

What needs to be checked into Git and what does not?

Files that are only relevant to the serving location or local environment should not be checked into Github as these files will vary between development, staging and production deployments and aren't at the core of the project. These are things like log files, databases, files system caches, user uploaded media files etc. (While they shouldn't be checked in to Github, they most likely should be backed up - particularly in the case of user uploaded media)

In the above image, both the Home Path and Environment Path represent these server files and are outside of the scope of Git and therefor not checked in.

Project Files

Now that we have identied our server files we can concentrate on those files relevant to the actual project.

Project files encompass everything relevant to your project and will be checked into Github. These are the Site Path and the Project Path in the above image. But there is a further distinction that needs to be made:

Which files are specific to the Django project itself and which files are not?

When deploying your project, there are some files that aren't necessarily related to the actual Django project but nonetheless are crucical for the project to work. These are things like configuration files, deployment scripts (fabric), documentation, PSDs etc. These non-django files are placed in the Site Path, while everything specifically related to Django is placed in the enclosed Project Path (In my previous post, all of these files were all placed together in a single folder which quickly became difficult to maintain.)

The Details

Now that a distinction has been made between the server files and the project files, we can go through each level in detail:

1. Home Path ~/Sites/

This is simply the directory where all sites are kept. I use virtualenvwrapper so this directory is my WORKON_HOME. On your production server, this might be the /srv/ folder.

2. Environment Path ~/Sites/football.com/

This is your local python environment, i.e. your virtualenv. When using virtualenvwrapper, my environment is created via mkvirtualenv --no-site-packages football.com and I can easily switch to it using the workon football.com command. If I am using plain virtualenv, this folder is create by mkdir football.com followed by virtualenv football.com and activated by source football.com/bin/activate.

3. Site Path ~/Sites/football.com/football.com/

4. Project Path ~/Sites/football.com/football.com/src/

This folder is the heart of your site and encapsulates all of the code relevant to your Django project. It is the folder that is created if you run the django-admin.py startproject command. Its naming is not particularly important but I call it src to convene with the unix folder structure conventions. It's important to remember that this folder needs to be added to your python path. If you are using virtualenvwrapper you can use the add2virtualenv command. If not you can add it manually


Extra Notes

continue the discussion on twitter @timmyomahony