Chicken Scratches

Eddie’s Django Tip #3: Don’t Mix Your Media

Don’t mix user-uploaded content with site-specific content with Django admin content.

This is a simple one, but I have seen projects where this was not followed, and the result was a real mess. so please, please, please do not mix your media!

There are (at least) three types of content that we can think of as “media” in a Django project: There is the Django admin media – the CSS files, images, and JavaScript that come with Django itself for use in the admin interface. Then there is your own static media that you use to style your site. And finally, there is user-uploaded content – things like profile pictures and so on. I recently took over a project where all three were in the same directory. I nearly wept.

In case it’s not obvious:

  • Django media stays with Django. Wherever you have Django installed, be it as a Python Egg, checked out from Subversion, or as part of your OS’s packaging system, keep it there. Use your web server’s configuration to map a URL to that path (taking appropriate security measures, of course). And set the ADMIN_MEDIA_PREFIX setting.

  • Your static media belongs in version control, probably with the rest of your source code. Depending on your work flow, you may want a separate system for the raw Photoshop or Gimp image files and the final web-ready images. I have an /img-src/ directory and a /static/images/ directory in every project, for example. The important thing is that they are separate from other media types, version controlled, and updated when the rest of the code is updated. Important note: Do not use Django’s MEDIA_ROOT and MEDIA_URL settings for this. These settings are for user-uploaded content. Django’s documentation is a little unclear on this point.

  • User-uploaded content stays separate. As always, use caution in what you let your users upload to your server. Validate the files if possible. Create your own file names; that is, don’t let the uploading user choose the server-side name of the file. Limit the upload size. And of course I don’t need to tell you not to run your FastCGI process as root, right? Right? (Believe it or not, the project I recently took over was set up like that, so I guess I do need to say it.)

Just as in real life, it’s important to pay attention to where you put stuff. A place for every file, and every file in its place.