60

I have a weird problem, I want to add a global query using context processors. This is how I did it by following:

made a processor.py in my app as such:

from myproject.myapp.models import Foo

def foos(request):
    return {'foos': Foo.objects.all()}

and at the end of my setting.py I have added this:

TEMPLATE_CONTEXT_PROCESSORS = ('myapp.processor.foos',)

Lastly I pass my view as this:

def index_view(request):

    return render_to_response('index.html', {}, context_instance=RequestContext(request))

and at my index.html template:

<select id="select_foo">
{% for foo in foos %}
    <option value="/{{ foo.slug }}">{{ foo.name }}</option>
{% endfor %}
</select>

And lastly my url:

(r'^$', 'myapp.views.index_view'),

My foos display without any problem, however my media_url and other contexts are gone. What can be the issue

Hellnar
  • 62,315
  • 79
  • 204
  • 279

3 Answers3

177

You need to add the default values of TEMPLATE_CONTEXT_PROCESSORS. However, instead of hard-coding those values, which will be tied to a specific version of Django, you can append your context processor to the default values by the following:

from django.conf import global_settings
TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
    "myapp.processor.foos",
)

Make sure to include the trailing comma in the tuple, so that Python recognizes it as a tuple.

Greg Glockner
  • 5,433
  • 2
  • 20
  • 23
  • 2
    Thanks for this tip! It's so much better than the more typical solution people suggest like TM's answer here. Having to specify the whole set of defaults just to add one always struck me as a kludge, and sure enough it came back to it me when I upgraded to django 1.3 and things didn't work because I was missing the default static context processor. – Vinay Pai May 16 '12 at 20:51
  • 8
    This is the better answer, because it will still work if the default processors change. – Canuck Sep 05 '12 at 10:58
  • 2
    @Greg Glockner that's a great tip, but where should I add that code? `settings.py`? – dialex Jun 22 '13 at 14:56
  • 2
    Yes, TEMPLATE_CONTEXT_PROCESSORS is typically defined in settings.py; see the Django settings documentation for details. – Greg Glockner Jun 25 '13 at 03:26
  • 3
    This is more convenient, but you need to be reviewing these settings anyway whenever you upgrade your version of Django. It's not really safe or smart to assume that you haven't lost something that you depended on or that you haven't added something you don't need. – TM. Sep 09 '14 at 19:17
  • How would you do that on *Django >= 1.8*? `from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS` and `TEMPLATES = [ { # … 'OPTIONS': { 'context_processors': TEMPLATE_CONTEXT_PROCESSORS + ( 'mymod.context_processors.some_processor', ), }, }, ]` still works, but `TEMPLATE_CONTEXT_PROCESSORS` will be gone in the future. – Brutus Nov 17 '15 at 13:10
  • 2
    Note: Since Django 1.9 global_settings.TEMPLATE_CONTEXT_PROCESSORS is a list, not a tuple, so the above needs be changed to `+ [ "myapp.processor.foos" ]` – Hein van Dyke Jul 28 '16 at 14:10
  • 2
    This answer could be updated for the new versions. In django 1.10 (and maybe before) the context processors are set under `TEMPLATES['OPTIONS']['context_processors']` so there is no top-level variable that defines that and `global_settings` does not contain it either. – Bakuriu Aug 28 '16 at 09:02
  • @Bakuriu do you have doc reference by any chance to know for < Django 3.0. Thanks – optimists Jun 15 '21 at 09:38
56

When you specify this:

TEMPLATE_CONTEXT_PROCESSORS = ('myapp.processor.foos',)

In your settings file, you are overriding the Django's default context processors. In order to extend the list, you need to include the default ones in your settings:

TEMPLATE_CONTEXT_PROCESSORS = (
    "django.core.context_processors.auth",
    "django.core.context_processors.debug",
    "django.core.context_processors.i18n",
    "django.core.context_processors.media",
    "myapp.processor.foos",
)

Note, the settings above are the defaults (plus your processor) for django 1.1.

justinsg
  • 738
  • 6
  • 11
TM.
  • 108,298
  • 33
  • 122
  • 127
  • I weirdly do not have TEMPLATE_CONTEXT_PROCESSORS in my settings.py , using the default Django 1.1.1 and media_url was working fine earlier. – Hellnar Feb 11 '10 at 18:37
  • 5
    That's because if you don't specify it, it uses the the default values specified in djangos settings. That's how all django settings work, they have a default that will be used if you don't have it in your `settings.py`. – TM. Feb 11 '10 at 18:37
  • Thanks now working! I was getting error so I removed "django.contrib.messages.context_processors.messages", I think this is for the development version of django, not 1.1.1 – Hellnar Feb 11 '10 at 18:41
  • Yes that's right, it is from the dev version. I updated my answer to show the 1.1 version. – TM. Feb 11 '10 at 18:43
  • 1
    In Django 1.5.x, you need to replace the first line with `django.contrib.auth.context_processors.auth` – Shailen Sep 11 '13 at 12:37
7

Here what worked for me for Django 1.3

TEMPLATE_CONTEXT_PROCESSORS = (
    "django.contrib.auth.context_processors.auth",
    "django.core.context_processors.debug",
    "django.core.context_processors.i18n",
    "django.core.context_processors.media",
    "django.core.context_processors.static",
    "django.contrib.messages.context_processors.messages",
    "myapp.processor.foos", )
David Dehghan
  • 22,159
  • 10
  • 107
  • 95