Область применения шаблона тега Django заставляет меня делать дополнительные запросы - PullRequest
5 голосов
/ 16 января 2010

Проблема в том, что если я вызову тег шаблона в блок и это наполняет меня переменную с обычным контекстом [varname] = что-то, затем, если мне нужна эта переменная в другой блок, я должен вызвать снова тег шаблона. Для меня это означает дополнительные запросы БД, что на самом деле что-то, чего я пытаюсь избежать.

Этот шаблонный тег вызывается в базовом шаблоне, который расширяется много других шаблонов, поэтому я не могу просто изменить все представления, чтобы передать что-то для контекста, это бессмысленно (принцип WET?)

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

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

Как бы вы решили эту проблему?

Ответы [ 4 ]

3 голосов
/ 16 января 2010

Вы сказали: «Этот тег шаблона вызывается в базовом шаблоне, который расширяется многими другими шаблонами».

Вопрос: этот тег вызывается из названного блока? Если это так, у вас есть пара потенциальных проблем.

  1. {% block %} помещает новый запрос в стек контекста и выскакивает его, когда он достигает соответствующего значения {{end endblock%} '. Это означает, что любое значение контекста, созданное в то время как в блоке, по существу вышло из области видимости при выходе из блока.

  2. Если этот блок переопределен каким-либо другим шаблоном, который расширяет базовый шаблон, значение может быть недоступно вообще, если вы не сделаете {{block.super}}, и даже тогда я не уверен, что значение будет доступно шаблону, выполняющему расширение.

Если тег не вызывается изнутри {% block %}, тогда значение контекста должно быть доступно для всего кода, который следует за ним, либо в базовом шаблоне, любых включенных шаблонах и (я думаю, ) любые расширяющиеся шаблоны.

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

В качестве альтернативы, если вы всегда обращаетесь к этому значению, вы можете просто поместить его в контекстный процессор , чтобы гарантировать его доступность.

Обновление для комментариев: ОК, время вводить большие пушки! Одна из наиболее раздражающих, давних ошибок в шаблонах Django заключается в том, что вызываемые объекты (т.е. функции) являются значениями контекста верхнего уровня (в отличие от функций, которые являются значениями / методами dict из значений контекста) не называются! Этот билет старше 2 лет, и для его исправления требуется около 10 строк кода. У нас есть несколько тяжеловесных вызовов БД, которые мы хотим сделать только , если кэш шаблона истек . Таким образом, мы а) MonkeyPatched шаблон _resolve_lookup() код, чтобы исправить вызываемую проблему, а затем б) функции карри, чтобы иметь все необходимые параметры при необходимости , потому что вы не можете передавать параметры в функции в шаблон "язык".

2 голосов
/ 16 января 2010

Я думаю, вы точно описали ограничения в этой ситуации. Наиболее приемлемые решения, вероятно, будут включать некоторую реструктуризацию цепочки наследования шаблонов, хотя трудно сказать, не зная деталей. Можете ли вы ввести новый шаблон в иерархию наследования, возможно, где-то около вершины пирамиды, но таким образом он наследуется только шаблонами, которым нужны эти данные, с одним блоком, который охватывает весь регион, в котором вам нужны эти данные? Затем этот большой блок можно разделить на более мелкие блоки, которые будут переопределены наследующими шаблонами. Если вы вызовите свой тег шаблона в начале этого блока, все блоки в нем (включая наследуемые шаблоны) будут иметь доступ к данным.

Обновление: я не могу сказать много, не видя ваших шаблонов, но введение нового шаблона в середине цепочки наследования очень редко включает «изменение всех шаблонов», в структуре нормального наследования это часто можно сделать с изменениями только один или два других шаблона. И я думаю, что то, что я предлагаю, на самом деле не хак, а просто лучший дизайн. Если вам нужна определенная часть данных в определенных частях вашего сайта, а не в других частях, должен быть конкретным единичным шаблоном, на который вы можете указать и сказать «этот шаблон представляет логический слой, на котором этот фрагмент данные вводятся и охватывают части сайта, на которых эти данные необходимы. "

0 голосов
/ 05 августа 2013

Только что натолкнулся на этот трюк от Ливиу, Agile Bear (вся заслуга ему)

Вместо того, чтобы делать

context['some_var']='some value'

сделать

context.dicts[0]['some_var']='some value'

Может быть не практикой кодирования книг, но работает достаточно хорошо

0 голосов
/ 16 января 2010

Вы просто пытаетесь сократить количество запросов к базе данных или ищете умное решение?

Если бы это было первое, я бы определенно занялся кэшированием. Будет ли фрагментарное кеширование работать в вашем случае? Если нет, возможно, вы могли бы поместить кэширование в код тега шаблона (при условии, что это не один из собственных тегов шаблона Django, который вы используете)?

...