Чтобы сформулировать свою проблему, вы хотите:
- Возьмите текст, который вы уже получили в строке (потому что вы загрузили его из базы данных),
- Возьмите больше текста, который вы собираетесь загрузить в строку (потому что вы знаете, откуда его загрузить),
- Сделать родительский шаблон из второй строки,
- Сделать дочерний шаблон из первой строки,
- Установить родительский шаблон (из первой строки) как родительский шаблон (из второй строки),
- Оценить дочерний шаблон.
- Самое главное, вы хотите, чтобы в дочернем шаблоне не было ничего похожего на
{% extends ...%}
, потому что ... почему?
- И, наконец, вы хотите сделать это без взлома ядра Django .
Краткий ответ:
Не возможно. Из коробки Джанго не будет делать то, что вы просите.
Длинный ответ:
Вся концепция наследования шаблонов в Django реализована через тег extends
. Точнее, это реализовано с помощью класса ExtendsNode модуля django.template.loader_tags, который создается при разборе тега extends
. Когда вы создаете Template (), он анализирует исходную строку и создает список узлов (хранится в списке узлов шаблона, как вы уже отмечали ранее). Позже вы можете визуализировать шаблон, используя любой контекст, который вам нравится, сколько угодно раз.
Грубо говоря, рендеринг работает, вызывая render () для каждого узла в списке узлов. Если первым узлом в списке узлов шаблона является ExtendsNode (а должен быть первым узлом), то происходит волшебство наследования шаблона. Когда создается ExtendsNode, ему присваивается список узлов шаблона и имя родителя (в виде строки (parent_name) или выражения (parent_name_expr). Когда визуализируется ExtendsNode, он будет использовать свой метод get_parent () для вызова get_template (parent_name) ), который вызовет механизм загрузчика шаблонов для загрузки родительского шаблона. Как только у него будет родительский шаблон, метод ExtendsNode :: render () будет использовать магию наследования шаблона.
Не стесняйтесь проверить код самостоятельно .
Чтобы не использовать загрузчик шаблонов, вам нужно сделать следующее:
- Создайте класс SpecialExtendsNode (ExtendsNode), переопределяя метод
__init__
и метод get_parent
.
- После создания шаблона из дочерней строки создайте экземпляр своего подкласса, инициализированный из родительского шаблона.
- Вставьте ваш экземпляр SpecialExtendsNode в заголовок списка узлов дочернего шаблона.
- Молитесь, чтобы разработчики Django ничего не изменили.
Просто чтобы упростить вам задачу, вот ваш класс:
class SpecialExtendsNode(ExtendsNode):
def __init__( self, nodelist, parent, name ):
self.myparent = parent
ExtendsNode.__init__( self, nodelist, name, None, None )
def get_parent( self ):
return self.myparent
И код для его использования будет выглядеть так:
parent = Template( parent_string )
child = Template( child_string )
hack = SpecialExtendsNode( child.nodelist, parent, "parent name" )
child.nodelist.insert( 0, hack )
output = child.render( context )
Теперь, когда я потратил время и силы, чтобы дать вам пистолет и зарядить его пулями, я попытаюсь убедить вас не нажимать на курок, а вместо этого делайте то, что рекомендовали все остальные.
Код, который я написал здесь, не проверяется на наличие ошибок и был написан для Django 1.2.Хотя я не тестировал его, я на 99% уверен, что он будет работать на Django 1.2.Я понятия не имею, будет ли он работать на любой другой версии Django.С другой стороны, помимо предоставления исходного кода, разработчики Django не документировали внутреннюю часть своего процессора шаблонов, кроме как для обеспечения документированных интерфейсов для написания новых тегов и фильтров шаблонов и документированного интерфейса для написания загрузчиков шаблонов (особенно упоминаниясценарий загрузки шаблона из базы данных).Это означает, что есть разумный случай, когда когда-нибудь разработчики Django могут переписать или значительно изменить механизм расширения шаблона.Если они это сделают, я на 100% гарантирую, что этот код сломается.Зачем?Потому что это хак.Вот как выглядит взломавший ядро Django .Он будет работать в течение дня, недели или даже месяцев, но рано или поздно вы (или программист, который придет за вами) обновится с Django 1.2 до более поздней версии, и тогда он сломается.И когда он сломается, я не смогу помочь вам, и разработчики Django все спросят: почему вы просто не написали загрузчик шаблонов?
Теперь скажите мнечто включает в себя больше взлома ядра Django - написание загрузчика шаблонов, который документирован и поддерживается разработчиками, или что я только что описал?