Serving media and static contents in Django
Django makes me write web application pretty easily. It is so fast that I could write my first web application in about 30 minutes – including downloading ‘Instant Django’ and setting it up.
On the other hand, understanding MEDIA_ROOT, MEDIA_URL and ADMIN_MEDIA – the ones in settings.py – was confusing. I read the documents, tutorials, comments and forums. Every time I read one of the above, it would appear that ‘voila, that is it; it is so easy’. But when I apply that into the program, it didn’t work. I was missing something seriously.
It was so frustrating to search, read and to code/re-code/re-re-code, only to find out that if admin css are served properly, the site’s css are not served properly. What follows below is how I got all of the pieces together. Surely, this information is available in Django Forums and other documents (which I refer at the end). I am writing this as a reference to myself and also with a hope that it might be useful to other such suffering souls.
Serving Admin CSS/JS (called Admin media)
This is represented in settings.py by ADMIN_MEDIA. It is better to serve this from Django’s admin folder itself, so that you don’t have to copy files, when you ‘svn update’ Django.
If ADMIN_MEDIA = ‘/adminmedia/’, then the development server interprets it to be served from the admin folder of Django (like Python25Libsite-packagesdjangocontribadminmedia). I preferred to keep it that way.
Coming to production, I use Apache alias as discussed in my other article. Here ‘/adminmedia’ should point to Django’s admin media folder. It goes as below:
SetHandler None
</Location>
Alias /adminmedia "C:/Python25/Lib/site-packages/django/contrib/admin/media"
<Directory "C:/Python25/Lib/site-packages/django/contrib/admin/media">
Options Indexes MultiViews
AllowOverride None
Order allow,deny
Allow from all
</Directory>
This is for Apache under Windows. I understand from the forums that the ‘Directory’ directive is not needed under Linux.
Serving site’s media
Now let us come to serving media for your site. Most probably you have this stored in a folder called ‘media’. My folder structure as in the picture.
To serve site’s media, I define a variable called ‘SITE_MEDIA’ as below:
PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))
SITE_MEDIA = '%s' % PROJECT_DIR
and in urls.py, I include this at the end:
urlpatterns += patterns('',
(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.SITE_MEDIA + '/media/'}),
)
and in base.html
This fundamentally means that the UrlHandler of Django will serve the ‘media/’ files from the SITE_MEDIA + ‘/media/’ directory.
Coming to production, alias comes to aid. I got the below alias for ‘/media/’.
SetHandler None
</Location>
Alias /media "C:/django_projects/cool/media"
<Directory "C:/django_projects/cool/media">
Options Indexes MultiViews
AllowOverride None
Order allow,deny
Allow from all
</Directory>
And of course you need to set DEBUG = False so that media files are served by Apache and not by Django.
Thanks, was struggling myself trying to serve both from the dev server, I confused ‘media’ as a convention where it’s more of a reserved url pattern. When I tried to serve anything from media it was routed to the admin directory.
The django site has a page on it here -
http://www.djangoproject.com/documentation/static_files/
…and are using a url pattern ‘site-media’, but I was not clear that ‘media’ itself was off limits.
I could think of better ways to spend a couple hours than fussing with it. This aside, I’m still impressed django.
ben
24 Jun 08 at 9:27 am