суббота, 20 марта 2010 г.

Разделяй и не властвуй?

Эксперименты показывают (в исходники самой Джанго пока не залезал толком), что Django Template Language имеет один не совсем неочевидный ньюанс: переменные, которые устанавливаются с помощью templatetag'ов в блоках, не "шарятся" между разными блоками. В итоге получается, что их надо устанавливать переменные заново в каждом из блоков, т.е. получаем как минимум лишний вызов, и возможно ещё и совершенно лишний запрос к базе.
Можно, конечно, результаты запроса кэшировать, если есть необходимось, но всё равно дублирование остаётся. С другой стороны, безусловно, установка переменных из шаблона не есть правильный подход, всё должно быть установлено по возможности на уровне view или в middleware. Но вот данные нужны на уровне именно самого шаблона, view находятся, в ныеншнем случае, в django CMS, а шаблоны могут туда передаваться разные, данные же эти нужны лишь в одном из них.
Получается или я что-то реально недопонимаю или всё выглядит немного некрасиво.

14 комментариев:

  1. Для этой цели можно использовать template tags или context processor, который будет добавлять глобальную переменную в context.

    ОтветитьУдалить
  2. В тексте же вроде написано, что вижу проблему именно в использовании template tags, а context processor не катит (если я всё правильно понимаю) - переменна нужна только лишь в данном шаблоне (для других она не имеет смысла).

    ОтветитьУдалить
  3. А как на счет установки переменной в RequestContext? Ведь template tag может принимать конекст в кчаестве параметра и, на сколько я понимаю, подифицировать его.

    ОтветитьУдалить
  4. Как раз про template tag'и, модифицирующие контекст, и написано в этом посте.

    ОтветитьУдалить
  5. угу а потом выясниться что ваши шаблоны не thread-safe когда захотите использовать кешируемые шаблоны из django 1.2

    ОтветитьУдалить
  6. А если попробовать прочитать, в чём же там кэширование заключается? :)
    Меня поражают комментаторы...

    ОтветитьУдалить
  7. А кешировать результат выполнения тега? Первый раз будет выполняться, второй просто возвращать данные из кеша.

    ОтветитьУдалить
  8. ну будет 2 обращения в кэш, от дублирования это не избавит, да и про кэширование я в посте упомянул

    ОтветитьУдалить
  9. Дублирование чего? Вызова тега?

    ОтветитьУдалить
  10. Конечно, да и к тому же очень непонятно как ты собираешься кэшировать результат тэга, который устанавливает значение переменной в контексте. Результатом его является ''

    ОтветитьУдалить
  11. http://dpaste.com/176418/
    значение вычисляется только при первом вызове тега. если значение уникально для каждого запроса или юзера, "подмешать" в ключ необходимую переменную из context

    ОтветитьУдалить
  12. И как это поможет избавиться от 2 вызовов одногои того же тэга?

    ОтветитьУдалить
  13. Никак, но я думаю это не так страшно как лишние запросы.
    Копания в коде натолкнули на такие манипуляции :)
    http://dpaste.com/176435/
    Устанавливает значение в контексте аналогично context_procesor, протестил: значение во втором блоке остается :)

    ОтветитьУдалить
  14. Интересно, спасибо, а про кэширование я в самом посте писал.

    ОтветитьУдалить