22nd
March 2014

AN UPDATED GENERAL DJANGO PROJECT (>= 1.5) STRUCTURE OR FOLDER LAYOUT

In a previous post I outlined a sane folder structure for a new Django project. Since then Django 1.5 (and 1.6) has been released along with an updated default folder structure. This post goes through some further tips on keeping your django project layout sensible.

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/.

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.

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

football : the documentation puts it best: "The inner (football)/ directory is the actual Python package for your project. Its name is the Python package name you’ll need to use to import anything inside it (e.g. mysite.urls).". Essentially, this is the location for files that are relevant to the entire project but not a particular application.

You can use this folder to place other files that don't fit in an app but are relevant to your overall project such as sitemaps.py, humans.txt, robots.txt, extra template tags (as long as you include football as an app) etc. In my previous post, this required a separate common or core app.

appX : these are your custom applications. In my previous post, I placed my applications in a separate folder for clarity. There are two ways to achieve this but I have since found that it leads to complications and a conflict between your folder structure and python path so I now just leave all apps sitting alongside one and other. This works well as this folder is much cleaner now that server-level files have been moved up to the parent directory (site path) and django-level files have been moved into the football module.

static : not to be confused with the static folder in the environment path, this static folder holds the files that you want collected by Django's contrib.staticfiles app. I prefer having a single folder in the project path as opposed to individual static folder in each application.

utils : a useful folder if you have small functions and modules that don't fit elsewhere (usually maths functions, string manipulation functions etc.)

requirements.txt : a list of all installed python libraries generated by pip freeze. I generally use pip-tools. As mentioned in the previous post: "Pip is great, but pip-tools is even better. It makes installing updating and dumping dependancies even easier."

Extra Notes

Backup: previously, I made sure all my source code was also in my Dropbox (symlinking the files to the appropriate virtualenv folder). I've since moved off Dropbox for backup (no encryption) and am now using Backblaze, so there is no need to do any symlinking.