Django TEMPLATE_CONTEXT_PROCESSORS are being called too many times

点点圈 提交于 2019-12-23 19:59:00

问题


I need show some statistic numbers in all pages, so I decided to use context processors. But I just figured out that my function is being called 2 to 7 times every page load. I am doing 4 queries inside the function, so I am getting a very bad performance. Every page load it can take up to 28 (4*7) queries...

I would like to know why this is happening and what can I do to avoid it.

settings.py

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.contrib.auth.context_processors.auth',
    'django.core.context_processors.request',
    'django.contrib.messages.context_processors.messages',
    'django.core.context_processors.static',
    'core.views.numbers',
)

views.py

def numeros(request):
      ...
    a=table1.objects.count()
    b=table2.objects.count()
    c=table3.objects.count()
    d=table4.objects.count()
     ...
    return {'a': a,
            'b': b,
            'c': c,
            'd': d,
            'e': e,
            'f': f,
            'g': g,
            'h': h
    }

[UPDATED - Thanks] @okm and @catherine provided very good and complementary explanation. Both were correct, as @okm said, the context processors was being called several time because I was using RequestContext more then once.

@catherine also is correct. We need pay extra attention what we put in context processors. I changed my code and I am just displaying the statistic numbers in the landing page.


回答1:


Setting function in TEMPLATE_CONTEXT_PROCESSORS have the advantage to use it in all pages. But be aware that even if you did not call it or use it, still it loads the queries because it directly call from the settings. It will result to bad performance. Use only the context processor when you have to use it almost in every template like the user or other parameters that don't have a lot of cost.




回答2:


The context processors are called one by one when a RequestContext instance is initialized, thus you may have multiple RequestContext instances being initialized. Could you debug to find out them, for example by using a RequestContext subclass to print when it's __init__ is being called?

Or you could return a lazy object which delays its evaluation until really needed, and see whether the count of the duplicated queries drops:

def numeros(request):
    return {'a': table1.objects.count,
            'b': table2.objects.count,
            ...}



回答3:


I had more or less the same problem. So went into one of the functions that was called by the RequestContext (from TEMPLATE_CONTEXT_PROCESSORS) and logged the traceback, to see where the response was trickered:

import traceback

logger.info(traceback.format_list(traceback.extract_stack()))

You could also print it if you have no logger activated.

In my case it was because I had debug_toolbar on, which also called RequestContext.



来源:https://stackoverflow.com/questions/15307449/django-template-context-processors-are-being-called-too-many-times

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!