Django: Why I made a template tag for MEDIA_URL

So, I want access to the MEDIA_URL settings in my templates. The template context processor django.core.context_processors.media provides that, right?  Well, only if your template gets passed an instance of django.template.RequestContext. This doesn’t happen automatically if you use django.shortcuts.render_to_response in your view function. If you want to reference MEDIA_URL in a base template which is extended by many other templates, then you can either add RequestContext instances to your views, or roll your own shortcut function which perhaps wraps render_to_response, etc.

Wouldn’t it be simpler if you could just get the MEDIA_URL as needed in your template without having to place this burden on your views?  It’s a bit strange that Django doesn’t provide a template tag for MEDIA_URL, since it does provide one for ADMIN_MEDIA_PREFIX. Perhaps the logic is that template context processors are global to a site (i.e., affecting all RequestContext instances), and MEDIA_URL is globally applicable, whereas ADMIN_MEDIA_PREFIX only applies to the admin site.

In addition to these issues I discovered that under certain conditions, such as those triggering server errors, the template context processors do not fire. So, for example, any dependencies in your 500.html template will not render properly. Not a huge issue in the larger scope of things, but why not fix that, too. No sense combining a server error with a crappy-looking error page if you can easily avoid it.

Advertisements

, ,

  1. #1 by Brandon on September 25, 2009 - 8:37 pm

    my 404 and 500 templates get the media url from requestcontext without issue.

    though i do like your idea, because you might want the media url in a small piece of an ajax view. this would allow you to retrieve as little from the server as possible without taking the entire request context into the tiny view.

  2. #2 by Mitch on December 9, 2009 - 1:28 pm

    Thank you! Not sure if its me or what, but somehow, I’ve been trying to get the MEDIA_URL to work in a template for a couple days… for whatever reason… I never saw anyone else mention you had to use the RequestContext instead of the render_to_response.

  3. #3 by Eric on March 10, 2010 - 8:02 pm

    Can you share the code for that? Thanks

  4. #4 by David Chandek-Stark on March 10, 2010 - 8:45 pm

    Sure, Eric. This is partial code for a custom template tag module. See http://docs.djangoproject.com/en/dev/howto/custom-template-tags/ for more details.

    from django import template
    from django.conf import settings
    
    register = template.Library()
    
    @register.simple_tag
    def media_url():
        return getattr(settings, 'MEDIA_URL', None)
  5. #5 by Eric on March 11, 2010 - 6:35 pm

    Thank you David.

    I do have a question, though. This works great for me but only on one page. How can this be? Shouldn’t this templatetag be available throughout the application?

    Thanks

  6. #6 by David Chandek-Stark on March 11, 2010 - 7:14 pm

    No, template tag libraries must be loaded explicitly with {% load %} in every template in which they are used. If you want a variable to be available in every template, then you probably want to write a template context processor — see http://docs.djangoproject.com/en/dev/ref/templates/api/.