dangerChihuahua007
dangerChihuahua007

Reputation: 20895

How come sending a request context gives me access to a setting in my Django template?

In my view, if I specify

def myView(request):
    return render_to_response('myTemplate.html', {'user': request.user,}, 
        context_instance=RequestContext(request))

then I can access settings such as STATIC_URL in myTemplate.html.

However, if I specify

def myView(request):
        return render_to_response('myTemplate.html', {'user': request.user,})

then I cannot access STATIC_URL. In this latter case, {{ STATIC_URL }} just yields an empty string in the rendered page. In the former case, {{ STATIC_URL }} yields the proper string for the static URL ("/static/").

Why do I need to send a request context to access the STATIC_URL setting in my template?

I am running Django 1.4 on Apache 2.

Upvotes: 1

Views: 232

Answers (3)

Paolo
Paolo

Reputation: 21056

To access the STATIC_URL setting you need to send a request context because by default the RequestContext instance is automatically populated with some variable, accordingly with the TEMPLATE_CONTEXT_PROCESSORS settings which, by default too, reads this:

(...
"django.core.context_processors.static",
...)

About the django.core.context_processors.static context processor, the docs states:

If TEMPLATE_CONTEXT_PROCESSORS contains this processor, every RequestContext will contain a variable STATIC_URL, providing the value of the STATIC_URL setting.

If instead, you don't specify the context_instance=RequestContext(request) part. Consider this signature:

render_to_response(template_name[, dictionary][, context_instance][, mimetype])

In this case a basic Context instance is used and (for this reason) only the given dictionary items get injected into the template. This dictionary could or couldn't contain the value of settings.STATIC_URL.

Note: as pointed out in another answer, since Django 1.3 you can directly use the render shortcut instead of render_to_response() with a context_instance argument.

References to official documentation:

Upvotes: 1

Tom
Tom

Reputation: 22841

Since you're on 1.4, use the newer render() shortcut. Then you can do:

def myView(request):
        return render(request, 'myTemplate.html', {'user': request.user,})

Upvotes: 0

diegueus9
diegueus9

Reputation: 31532

Read the docs for a better answer. But there is the short answer:

This is because of DRY (Don´t Repeat Yourself), think this: what if you need set the same variable in all the templates through all the views?: context_processors, are methods that add variables to your templates in a more ordered way.

I quote:

Django comes with a special Context class, django.template.RequestContext, that acts slightly differently than the normal django.template.Context. The first difference is that it takes an HttpRequest as its first argument. For example:

c = RequestContext(request, {
    'foo': 'bar',
})

The second difference is that it automatically populates the context with a few variables, according to your TEMPLATE_CONTEXT_PROCESSORS setting.

Upvotes: 3

Related Questions