Django TEMPLATE_CONTEXT_PROCESSORS被调用的次数太多了

时间:2013-03-09 05:14:59

标签: django django-templates django-context

我需要在所有页面中显示一些统计数字,所以我决定使用上下文处理器。但我只是发现每个页面加载时我的函数被调用了2到7次。我在函数内部进行了4次查询,因此我的性能非常糟糕。每个页面加载最多可能需要28(4 * 7)个查询...

我想知道为什么会这样,我该怎么做才能避免它。

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
    }

[更新 - 谢谢] @okm和@catherine提供了很好的补充说明。两者都是正确的,正如@okm所说,上下文处理器被多次调用,因为我多次使用RequestContext。

@catherine也是对的。我们需要特别注意我们在上下文处理器中添加的内容。我更改了代码,我只是在着陆页中显示统计数字。

3 个答案:

答案 0 :(得分:4)

初始化RequestContext实例时,将逐个调用上下文处理器,因此可能会初始化多个RequestContext实例。您可以调试以找出它们,例如在调用__init__时使用RequestContext子类进行打印吗?

或者您可以返回一个延迟评估的惰性对象,直到确实需要为止,并查看重复查询的计数是否下降:

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

答案 1 :(得分:3)

TEMPLATE_CONTEXT_PROCESSORS中的设置功能具有在所有页面中使用它的优点。但请注意,即使您没有调用它或使用它,它仍会加载查询,因为它直接从设置调用。这将导致糟糕的表现。当你必须在每个模板中使用它时,只使用上下文处理器,例如用户或其他没有很多成本的参数。

答案 2 :(得分:0)

我或多或少有同样的问题。因此,进入RequestContext调用的一个函数(来自TEMPLATE_CONTEXT_PROCESSORS)并记录回溯,以查看响应的位置:

import traceback

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

如果您没有激活记录器,也可以打印它。

在我的情况下,这是因为我打开了debug_toolbar,它也称为RequestContext。