Django static media always returning 404 not found

6 October 2010

I spent too long tonight figuring out a weird problem.

On a dev server, I was using django.views.static.serve to serve media files. But it was returning 404 (not found) for any file.

The requests for media files weren’t even showing up in Django’s built-in server’s output. That had me baffled until I dug deep enough in Django’s code to figure it out.

The ADMIN_MEDIA_PREFIX was the same as MEDIA_URL. That was it.

Django’s built-in server doesn’t log requests for admin media, so that’s why there was no log output.

The built-in server also handles admin media separately, so when I tried to request a media file, it intercepted and looked for it in the admin media.

The solution is for the ADMIN_MEDIA_PREFIX to be different from MEDIA_URL, e.g. /media/ and /media/admin/.

Filed under: Django — Scott @ 10:19 pm

6 Comments »

  1. It’s not your fault. By default, Django puts the following in settings.py for a new site:

    # URL that handles the media served from MEDIA_ROOT. Make sure to use a
    # trailing slash if there is a path component (optional in other cases).
    # Examples: “http://media.lawrence.com”, “http://example.com/media/”
    MEDIA_URL = ”

    # URL prefix for admin media — CSS, JavaScript and images. Make sure to use a
    # trailing slash.
    # Examples: “http://foo.com/media/”, “/media/”.
    ADMIN_MEDIA_PREFIX = ‘/media/’

    One of my biggest Django peeves is the built-in confusion over the right way to serve static media and refer to it in templates. The default source code above strongly implies doing it one (confusing) way, while the docs (http://docs.djangoproject.com/en/dev/howto/static-files/) suggest something completely different (setting up a STATIC_DOC_ROOT variable).

    Comment by Brent Tubbs — 7 October 2010 @ 3:29 am

  2. Ah, if I’d read the docs I might have seen this warning:

    “Be careful not to use the same path as your ADMIN_MEDIA_PREFIX (which defaults to /media/) as this will overwrite your URLconf entry.”

    Comment by Scott — 7 October 2010 @ 9:15 am

  3. The term “media” always struck me as a poor choice, as it means both everything and nothing and is guaranteed to confuse a Django newcomer (as it once did confuse me). Which is why my Django deployments are set up with what I consider less confusing terminology:

    /upload – the stuff that users uploaded to the server, i.e. what Django refers to as media (served under MEDIA_URL and stored in MEDIA_ROOT on the filesystem).
    /static – the static part of my project/site, such as icons, Javascript files, CSS, etc. (I keep this well separate from /upload, as it is truly static and lives in version control, unlike /upload)
    /adminmedia – the static parts of Django’s admin interface, which is served under ADMIN_MEDIA_PREFIX and part of Django. Arguably this should live under /static/admin, but I prefer the clean separation in case I need to more one or the other to a separate host for whatever reason (performance, CDN, …)

    Hopefully if Django ever decides to make some rather backwards-incompatible changes, this gets cleaned up :-)

    Comment by Ingmar — 8 October 2010 @ 5:03 pm

  4. I’ve been struggling with *exactly* the same problem. Thanks for posting!

    Comment by David Talbot — 21 November 2010 @ 11:00 am

  5. wow very helpful, I hadn’t changed me admin-media url and was comparing my settings file between two django apps trying to figure out why the static server was returning 404. By default a django settings project should set them differently to avoid this problem.

    Comment by morgan — 14 February 2011 @ 1:45 am

  6. You are a star! Thanks mate :)

    Comment by Glyn Mooney — 14 April 2011 @ 10:07 am

RSS feed for comments on this post.

Leave a comment