2

I created a simple custom context processor that needs to only be run once per request. After putting in some logging hooks I found that it is being called twice per request.

Is this a known "feature" that a missed in the docs? Is it related to the number of templates in the inheritance tree? Is it a bug in 1.03?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
  • I looked into this further and it seems that EACH context processor gets executed once per template in the template inheritance tree. I have two templates - base.html and homepage.html. This seems really inefficient and I'm a little surprised it would be happening. I'm hoping it's just a silly oversight on my part. –  Sep 19 '09 at 04:03
  • 1
    Seems ok to me. You've got two templates, both need the proper context. This sounds like the interceptor stack in struts. – Seth Sep 19 '09 at 04:39
  • 1
    What logging hooks did you use? Sometimes if you're using Python's logging package and inadvertently add multiple handlers, you get messages output twice. Check the timestamps of those events. – Vinay Sajip Sep 19 '09 at 07:47
  • Maybe this helps someone. It happens when using django-debug-toolbar middleware. – Martin Jul 06 '12 at 14:31

6 Answers6

2

This is not expected behavior. Context processor are executed once each time a RequestContext is instantiated). In the case of template inheritance, the same context instance is passed up to the parent template, so that shouldn't cause another execution of the context processors. Either your logging is misleading (see @Vinay Sajip's comment), or you need to figure out where in your code an extra RequestContext might be executed on each request (are you using an inclusion tag or some other custom template tag that renders a template and instantiates RequestContext?)

EDIT Sorry, by "inclusion tag" I meant (in the generic sense) some tag that renders another template, not any tag that uses the inclusion_tag decorator. A regular inclusion_tag that takes context should simply pass along the existing context object, not instantiate a new RequestContext.

One thing you could try is to place an "import pdb; pdb.set_trace()" in your context processor, run the code in the Django dev server, and in the console examine the stack trace with pdb each time your context processor gets hit, to see where it's being called from.

Carl Meyer
  • 122,012
  • 20
  • 106
  • 116
  • I am using a custom inclusion tag that takes 'context' as an argument. Given that is this expected behavior? I hadn't realized that inclusion tags caused the context processor to be run again. –  Sep 20 '09 at 01:49
2

In my case this bug occur when using django debug_toolbar. To avoid this try to comment

debug_toolbar.middleware.DebugToolbarMiddleware

Artem Shmatkov
  • 1,434
  • 5
  • 22
  • 41
Jlexa
  • 21
  • 2
  • Same here, commenting out the DebugToolbarMiddleware fixed it. – Maik Hoepfel Nov 06 '13 at 17:57
  • You can also just comment out 'debug_toolbar.panels.template.TemplateDebugPanel' and get the other Debug Toolbar Panels. There is a Github issue ticket for this here: https://github.com/django-debug-toolbar/django-debug-toolbar/issues/353 – seddonym Nov 29 '13 at 10:19
1

I figured out the issue. If a dictionary other than the original context is returned then the context processor seems to be executed again. Not sure why, and I can't be sure because I didn't look at the underlying code, but the after I updated the original context and returned that the issue went away. Thanks.

  • it's been a long time, but can you explain your solution a little bit more please ? :) Thanks – fceruti Jun 11 '11 at 05:48
  • 4
    I had the same problem but the issue for me was that django-debug-toolbar seems to create its own RequestContext which causes all context processors to run again. I couldn't find RequestContext while grepping its source but removing it from INSTALLED_APPS and MIDDLEWARE_CLASSES definitely fixed the problem. – Kyle MacFarlane Jul 19 '12 at 06:12
0

Is this happening on a production webserver, Apache etc, or just in the built in development server? I've noticed similar behaviour locally on occassion, but I'm pretty sure it's just a quirk in the runserver.

Greg
  • 9,963
  • 5
  • 43
  • 46
0

Hope this helps:

In my case the issue was a templatetag, namely: providers_media_js from allauth package.

Try not to return anything in your context processor and see if the issue persists. Then try to spot which variable is responsible for this problem.

Aleph-null
  • 321
  • 2
  • 7
0

For future reference -- my problem was a render_to_string inside a view function, causing the context processor to be executed twice:

comments = render_to_string('comments.html', {'comments': comments_list}, request)

This call was cached, so it was kinda difficult to identify where the problem was. Anyway, I solved it by removing the request context from the render_to_string call, since I didn't need it for this particular case:

comments = render_to_string('comments.html', {'comments': comments_list})

Later on I refactored the code and removed the render_to_string all together, and cached the snippet directly in the template. But there are legit cases for using render_to_string inside a view function (such as rendering an email template for example), so this may cause some issues.

Vitor Freitas
  • 3,550
  • 1
  • 24
  • 35