A General Django Project Structure or Folder Layout

UPDATE 03/14: I've written a new post regarding project layout with Django >=1.5. You can read it here

I’m always trying to tidy up my project layout so that they are easy to maintain as well as recoverable (in the inevitable case that I accidentally delete something). There are plenty of articles on the web discussing different layouts for small to medium sized Django projects. I’ve learned a lot from those and I’d like to add my own 2c when it comes to deploying a new project.

The following is my general layout. The root folder foo.com is generated via virtualenv and django_root is the guts of my project:

foo.com     < -- site root
  db/
  media/
  static/
  src/
  bin/
  include/
  lib/
  django_root/     < -- project root (checked into Github)
    .git
    apps/
      bar/
      baz/
    common/
    confs/
      production/
        nginx.conf
        supervisor.conf
        wsgi.py
          gunicorn.py
          ...
      development/
      staging/
    docs/
    fixtures/
    libs/
    media/
    psds/
    requirements.txt
    settings/
      paths.py
      database.py # Not checked into Github
      private.py # Not checked into Github
      default.py
      custom.py
    static/
      compressed/
      fonts/
      images/
      javascripts/
      less/sass.../
      stylesheets/
    templates/
    README.md

Things To Note

  • Most importantly - everything that is important is stored within django_root and therefore tucked away in version control (GitHub).
  • Virtualenvwrapper: The root folder foo.com is generated via virtualenv and virtualenvwrapper, which makes switching projects sensible and easy via workon foo.com.
  • Project Root vs. Site Root & Git: My project root django_root is checked into Git, the site root isn’t: everything that is specific to your project should be under django_root, everything that is generic to your site should be under site_root
  • Cloud Backup: I use Dropbox 100Gb so I keep the project root in Dropbox (under ./Drobox/Development/sites/foo.com) while keeping the actual site root outside of Dropbox (to save Dropbox space). I then symlink from one to the other. This gives an extra layer of protection from accidentally deleting everything (which I’ve previously done twice).
  • Dedicated Application Subfolder: I use an apps folder within the project root to hold all my custom applications. I find this a cleaner than having them sit in the root of the project folder. For bigger projects, I split these apps into further subfolders (admin, content …)
  • General (Non-Application-Specific) Files & Modules: I have a common folder which is added to the python path and contains modules which don’t belong in an application; sitemaps.py, general utility template tags, standalone utility modules, general context processors or middleware, error views etc.
  • General Libraries: I use the libs folder to hold modules that aren’t django applications, arn’t particularly related to django (like in the common folder) but are being used internally by one or more applications in some form. Ideally, any library you write should be wrapped up as a module in pypi so that it can be installed with pip, but this is a good alternative for small custom libraries.
  • Server/Dev Configuration: The conf folder holds all files related to the server configuration of the project. The files contained within are symlinked to the appropriate locations on the dev/production server. Having them here means you will always have them under source control (make sure not to include passwords)!
  • Fixtures: The fixtures folder can be useful if there are certain sets of data you want to make sure you don’t lose. When developing, I am constantly wiping the test DB, so recreating specific fixtures is a pain. Use loaddata and dumpdata regularly. If you don’t care about the actual contents of your fixtures, you can use something like django-dilla to generate spam values quickly.
  • Project Media: There are two media folders; one in the site root that will be used by django when uploading files etc, and another in the project root; I use the one in the project root to hold media that I create during development
  • Photoshop & General Resources: I usually check all photoshop files I use during development into Git as I will probably delete them or lose them them otherwise.
  • Pip, Pip-Tools & Requirements File: Pip is great, but pip-tools is even better. It makes installing updating and dumping dependancies even easier. Dumping your requirements with vanilla pip is done via pip freeze > requirements.txt and with pip-tools using pip-dump > requirements.txt. This makes it very easy to move from one server to the other.
  • Settings: I try to be as versbose as possible in the settings folder; default.py holds settings relevant to the base django install, custom.py holds settings for all my installed apps - be them home made or modules installed via pip -, database.py contains connection settings and passwords, and isn’t checked into Git. private.py holds private keys, sentry DSNs etc. and also isn’t checked into Git. Then there are specific settings files for both production and development etc. These are called by the application server and import everything else.