2013-03-09 4 views
2

Мне нужно показать некоторые статистические числа на всех страницах, поэтому я решил использовать контекстные процессоры. Но я просто понял, что моя функция называется от 2 до 7 раз за каждую загрузку страницы. Я делаю 4 запроса внутри функции, поэтому я получаю очень плохую производительность. Каждая загрузка страницы может занимать до 28 (4 * 7) запросов ...Django TEMPLATE_CONTEXT_PROCESSORS вызываются слишком много раз

Я хотел бы знать, почему это происходит и что я могу сделать, чтобы избежать этого.

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

Функция настройки в TEMPLATE_CONTEXT_PROCESSORS имеет преимущество, чтобы использовать ее на всех страницах. Но имейте в виду, что даже если вы не вызывали его или не использовали, он все равно загружает запросы, потому что он напрямую вызывает настройки. Это приведет к плохой производительности. Используйте только контекстный процессор, когда вы должны использовать его почти в каждом шаблоне, таком как пользователь или другие параметры, которые не имеют большой стоимости.

+1

Контекстные процессоры * не * напрямую вызываются из настроек, они вызывается, когда инициализируется 'RequestContext'. Вы можете проверить код [здесь] (https://github.com/django/django/blob/stable/1.5.x/django/template/context.py#L170) – okm

+0

@okm благодарит за информацию. Я никогда не пользовался RequestContext на мой взгляд. – catherine

4

Контекстные процессоры вызываются один за другим, когда инициализируется экземпляр RequestContext, поэтому вы можете инициализировать несколько экземпляров RequestContext. Не могли бы вы отлаживать их, например, используя подклассу RequestContext для печати при вызове __init__?

Или вы могли бы вернуть ленивый объект, который задерживает свою оценку до тех пор, на самом деле не нужно, и увидеть падает ли счетчик дублированных запросов:

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

у меня было больше или меньше с той же проблемой. Так вошел в одну из функций, которые называли по RequestContext (от TEMPLATE_CONTEXT_PROCESSORS) и зарегистрированных в отслеживающий, чтобы увидеть, где ответ trickered:

import traceback 

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

Вы также можете распечатать его, если у вас нет регистратора активирована.

В моем случае это было потому, что у меня был debug_toolbar on, который также назывался RequestContext.

 Смежные вопросы

  • Нет связанных вопросов^_^