Rick Hurst Web Developer in Bristol, UK


A few notes on image uploading and configuration in Django

I recently added image uploading to Too Old To Skate, and not having set up a “normal” django site for a while, hit about every stumbling block possible, so here are a few notes. Please bear in mind there may be other, better ways to achieve this – i’d love to hear them.

Adding an Image field

This is achieved simply by adding an ImageField to your model, e.g.:-

photo = models.ImageField(upload_to='image_uploads', blank=True)

Separate static and media directories

The static folder is where your local site assets go e.g. CSS and Javascript. Locally these are served up from /static/ by the django dev server, and on a live site this should be set up as aliases to serve by your web server (in my case Apache).

The media folder is where user-uploaded files go, in subdirectories specified in ‘upload_to’ in your image field in the model. The root is configured in settings.py, but unlike the static folder you will need to do some configuration to get the local dev server serving files up from this directory (and its sub-directories). The location of the media root needs to be different to static root, which threw me slightly, though I guess it makes sense to keep your own static assets and uploaded media entirely separate.

To get the local dev server serving up files from /media and its subdirectories, add this to urls.py:-

# you'll need to add this if you aren't already importing settings
from django.conf import settings

if settings.DEBUG:
urlpatterns += patterns('',
(r'^media/(?P.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT}))


Permissions need to be set on your media folder to allow uploaded files to be saved. This depends on your set-up, but for me adding write permissions for group allowed apache + wsgi + python (whichever one of those it appears as?) to save files and create directories.

PIL and libjpeg

As usual this caused me massive headaches to get running both locally and on my web server, and as usual I tried so many things i’m not 100% sure which steps actually made a difference in the end!