Joseph Jude

Technology, Psychology, and Story Telling

Serving media and static contents in Django

Posted: Tags: code,python,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:

  <Location "/adminmedia">
  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

static content folder

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:

  import os
  PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))
  SITE_MEDIA = '%s' % PROJECT_DIR`

and in urls.py, I include this at the end:

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

and in base.html

  <link rel="stylesheet" type="text/css" href="/media/css/sol.css" />

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

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


Comments

comments powered by Disqus