3

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

我想知道为什么会发生这种情况以及我能做些什么来避免它。

设置.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',
)

视图.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 也是正确的。我们需要特别注意我们在上下文处理器中放置的内容。我更改了我的代码,我只是在登录页面中显示统计数字。

4

3 回答 3

5

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

或者您可以返回一个延迟其评估直到真正需要的延迟对象,并查看重复查询的计数是否下降:

def numeros(request):
    return {'a': table1.objects.count,
            'b': table2.objects.count,
            ...}
于 2013-03-09T09:02:04.317 回答
3

TEMPLATE_CONTEXT_PROCESSORS 中的设置函数有利于在所有页面中使用它。但请注意,即使您没有调用或使用它,它仍然会加载查询,因为它直接从设置中调用。这将导致性能不佳。当您几乎必须在每个模板(如用户或其他成本不高的参数)中使用上下文处理器时,请仅使用上下文处理器。

于 2013-03-09T06:08:17.963 回答
0

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

import traceback

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

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

就我而言,这是因为我打开了 debug_toolbar,它也称为 RequestContext。

于 2013-04-11T10:53:14.960 回答