[Fixed]-How should Django Apps bundle static media?


Convention is to put static media in either media/appname/ or static/appname/ within the app (similar to templates).

For using apps in your project that come with media, I strongly recommend using django-staticfiles. It will automatically serve media (including media within apps) in development through a view that replaces django.views.static.serve, and it comes with a build_static management command that will copy media from all apps into a single directory for serving in production.

Update: django-staticfiles has become part of Django 1.3. It now expects app media to live in a “static/” subdirectory of the app, not “media/”. And the management command is now “collectstatic.”


The only app I know of that deals with this without any intervention is the rather wonderful django-debug-toolbar, though it’s arguable that this isn’t a great example, since it’s an app specifically designed for debug mode only.

The way it deals with it is that it serves its media through Django itself – see the source for urls.py:

url(r'^%s/m/(.*)$' % _PREFIX, 'debug_toolbar.views.debug_media'),

In general, this is a bad idea (you don’t want to serve static files through Django), per this comment from the documentation:

[Serving static files through Django] is inefficient and
insecure. Do not use this in a
production setting. Use this only for

Obviously, the django-debug-toolbar is only used for development, so I think its method of deployment makes sense, but this is very much an exception.

In general, the best way I know to do it is to create symbolic links wherever your media is stored to the media inside your app code. For example, create a folder called media within your app, and then require users installing your app to either add a symbolic link from their media directory, or copy the whole thing.


i usually put apps media in ./apps/appname/static (my apps resides in an apps subfolder)

then i have something similar in the vhost in apache :

AliasMatch ^/apps/([^/]+)/static/(.*) /home/django/projectname/apps/$1/static/$2
<DirectoryMatch "^/home/django/projectname/apps/([^/]+)/static/*">
        Order deny,allow
        Options -Indexes
        deny from all
        Options +FollowSymLinks
        <FilesMatch "\.(flv|gif|jpg|jpeg|png|ico|swf|js|css|pdf|txt|htm|html|json)$">
                allow from all

i also have this in my urls.py for dev server (use only for debug) :

def statics_wrapper(request, **dict):
    from django.views import static
    return static.serve(request, dict['path'], document_root = os.path.join(settings.BASE_DIR, 'apps', dict['app'], 'static'), show_indexes=True)
urlpatterns += patterns('', (r'^apps/(?P<app>[^/]+)/static/(?P<path>.+)$', statics_wrapper))

this is very handy because statics url are simply mapped to filesystem, eg :

http://wwww.ecample.com/apps/calendar/static/js/calendar.js resides in [BASE_DIR]/apps/calendar/static/js/calendar.js

hope this helps


Leave a comment