问题
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