Пользовательский процессор контекста Django вызывается дважды за запрос

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

Это известная «функция», которая отсутствует в документах? Связано ли это с количеством шаблонов в дереве наследования? Это ошибка в 1.03?


person Community    schedule 19.09.2009    source источник
comment
Я изучил это дальше, и кажется, что КАЖДЫЙ процессор контекста выполняется один раз для каждого шаблона в дереве наследования шаблонов. У меня есть два шаблона — base.html и homepage.html. Это кажется действительно неэффективным, и я немного удивлен, что это произойдет. Надеюсь, это просто глупая оплошность с моей стороны.   -  person    schedule 19.09.2009
comment
Мне кажется, все в порядке. У вас есть два шаблона, оба нуждаются в правильном контексте. Это похоже на стек перехватчиков в распорках.   -  person Seth    schedule 19.09.2009
comment
Какие ловушки для журналирования вы использовали? Иногда, если вы используете пакет протоколирования Python и непреднамеренно добавляете несколько обработчиков, сообщения выводятся дважды. Проверьте временные метки этих событий.   -  person Vinay Sajip    schedule 19.09.2009
comment
Может быть, это кому-то поможет. Это происходит при использовании промежуточного программного обеспечения django-debug-toolbar.   -  person Martin    schedule 06.07.2012


Ответы (6)


Это не ожидаемое поведение. Процессор контекста выполняется один раз каждый раз при создании экземпляра RequestContext< /а>). В случае наследования шаблона один и тот же экземпляр контекста передается родительскому шаблону, поэтому это не должно вызывать повторного выполнения процессоров контекста. Либо ваше ведение журнала вводит в заблуждение (см. комментарий @Vinay Sajip), либо вам нужно выяснить, где в вашем коде может выполняться дополнительный RequestContext для каждого запроса (используете ли вы тег включения или какой-либо другой настраиваемый тег шаблона, который отображает шаблон и создает экземпляр RequestContext?)

EDIT Извините, под «тегом включения» я имел в виду (в общем смысле) некоторый тег, который отображает другой шаблон, а не любой тег, который использует декоратор include_tag. Обычный include_tag, принимающий контекст, должен просто передавать существующий объект контекста, а не создавать экземпляр нового RequestContext.

Одна вещь, которую вы можете попробовать, это поместить «import pdb; pdb.set_trace()» в ваш контекстный процессор, запустить код на сервере разработки Django и в консоли проверять трассировку стека с помощью pdb каждый раз, когда ваш контекстный процессор срабатывает. , чтобы увидеть, откуда он вызывается.

person Carl Meyer    schedule 19.09.2009
comment
Я использую настраиваемый тег включения, который принимает «контекст» в качестве аргумента. Учитывая, что это ожидаемое поведение? Я не осознавал, что теги включения вызывают повторный запуск процессора контекста. - person ; 20.09.2009

В моем случае эта ошибка возникает при использовании django debug_toolbar. Чтобы избежать этого, попробуйте прокомментировать

debug_toolbar.middleware.DebugToolbarMiddleware

person Jlexa    schedule 24.03.2013
comment
То же самое здесь, комментирование DebugToolbarMiddleware исправило это. - person Maik Hoepfel; 06.11.2013
comment
Вы также можете просто закомментировать «debug_toolbar.panels.template.TemplateDebugPanel» и получить другие панели панели инструментов отладки. Для этого есть билет на Github: github.com/ django-debug-toolbar/django-debug-toolbar/issues/353 - person seddonym; 29.11.2013

Я понял проблему. Если возвращается словарь, отличный от исходного контекста, то кажется, что процессор контекста выполняется снова. Не уверен, почему, и я не могу быть уверен, потому что я не смотрел на базовый код, но после того, как я обновил исходный контекст и вернулся, проблема исчезла. Спасибо.

person Community    schedule 29.09.2009
comment
это было давно, но не могли бы вы объяснить свое решение немного подробнее, пожалуйста? :) Спасибо - person fceruti; 11.06.2011
comment
У меня была та же проблема, но проблема для меня заключалась в том, что django-debug-toolbar, похоже, создает свой собственный RequestContext, который заставляет все процессоры контекста снова запускаться. Я не смог найти RequestContext при поиске его источника, но удаление его из INSTALLED_APPS и MIDDLEWARE_CLASSES определенно устранило проблему. - person Kyle MacFarlane; 19.07.2012

Это происходит на производственном веб-сервере, Apache и т. д. или только на встроенном сервере разработки? Иногда я замечал подобное поведение локально, но я почти уверен, что это просто особенность сервера выполнения.

person Greg    schedule 25.09.2009

Надеюсь это поможет:

В моем случае проблема заключалась в теге шаблона, а именно: provider_media_js из пакета allauth.

Постарайтесь ничего не возвращать в вашем процессоре контекста и посмотрите, сохраняется ли проблема. Затем попытайтесь определить, какая переменная отвечает за эту проблему.

person Aleph-null    schedule 22.12.2017

Для справки в будущем - моя проблема заключалась в render_to_string внутри функции представления, из-за чего процессор контекста выполнялся дважды:

comments = render_to_string('comments.html', {'comments': comments_list}, request)

Этот вызов был закэширован, поэтому было довольно сложно определить, в чем проблема. Во всяком случае, я решил это, удалив контекст запроса из вызова render_to_string, так как он мне не нужен для этого конкретного случая:

comments = render_to_string('comments.html', {'comments': comments_list})

Позже я провел рефакторинг кода и полностью удалил render_to_string, а фрагмент закэшировал прямо в шаблоне. Но есть законные случаи использования render_to_string внутри функции представления (например, рендеринг шаблона электронной почты), поэтому это может вызвать некоторые проблемы.

person Vitor Freitas    schedule 20.03.2018