Получить имя шаблона в теге шаблона (Django) - PullRequest
7 голосов
/ 23 ноября 2011

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

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

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

EDIT

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

class Tag(models.Model):
    template = models.CharFIeld(max_length=50)
    name = models.CharField(max_length=100)
    plugins = models.ForeignKey(PluginBase)

если есть объект тега, то он отображает все объекты плагина, если нет, он создает объект тега, уникальный для имени, указанного в теге шаблона, и имени шаблона, если получение имени шаблона невозможно, то я думаю можно просто сделать его уникальным для каждого имени. Весь тег похож на заполнитель для тех, кто знаком с django-cms

Ответы [ 2 ]

3 голосов
/ 23 ноября 2011

Глядя на источник, в то время как объект Template будет иметь доступ к имени шаблона (через .name), это значение никогда не передается объекту Parser ипоэтому он недоступен для тегов шаблона.

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

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


Из-за академического интереса у меня была быстрая скрипка, чтобы посмотреть, возможно ли это.Насколько я вижу, это возможно, но не без изменения или исправления источника django.

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

Изменяя django.template.base.py со следующими изменениями, мы добавляем атрибут .template_name к объекту синтаксического анализатора, делая его доступным для тегов шаблона.

  1. Добавлен необязательный аргумент для compile_string
  2. Добавлено имя шаблона в качестве дополнительного атрибута для анализатора
  3. Передается в имени шаблона при вызове compile_string()

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

from django.template.base import Node, Library
register = Library()

class TemplateNameNode(Node):
    def __init__(self, template_name):
        self.name = template_name

    def render(self, context):
        return self.name.upper()

@register.tag
def caps_template_name(parser, token):
     return TemplateNameNode(parser.template_name)

и следующий шаблон:

{% load mytags %}
Template name in caps: {% caps_template_name %}

Кажется, это работает при тестировании в ./manage.py shell:

>>> from django.template import loader, Context
>>> t = loader.get_template("test.html")
>>> t.render(Context({}))
u'\nTemplate name in caps: TEST.HTML\n'

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

2 голосов
/ 23 ноября 2011

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

Что будет работать, так это создать оболочку для вызовов рендеринга, которые вы делаете,Допустим, в настоящее время вы делаете следующее:

from django.shortcuts import render
def index(request):
    return render(request, 'app/index.html', { 'foo': 'bar', })

Если вы создадите для этого собственную оболочку, вы можете добавить имя шаблона в словарь до того, как произойдет фактический рендеринг:

from django.shortcuts import render
def myrender(request, template, dictionary):
    dictionary.update({'template_name': template})
    return render(request, template, dictionary)

Затем в ваших представлениях измените ее следующим образом (при условии, что вы сохранили указанную выше функцию в myutils.py, и она доступна по вашему пути):

#from django.shortcuts import render <- delete this line
from myutils import myrender as render
def index(request):
    return render(request, 'app/index.html', { 'foo': 'bar', })

Теперь все ваши вызовы render обновят словарьс именем шаблона.В любом шаблоне просто используйте {{ template_name }}, чтобы получить имя.Конечно, вы также можете обновить другую функцию рендеринга, например, render_to_response и т. П.

Кроме того, import myrender as render может сбить вас с толку, а может и не сбить вас с толку, потому что она названа как функция Django.Если это так, просто импортируйте его без "as render" и замените все render вызовы на myrender.Лично я предпочел бы это, так как это делает его заменой существующих функций рендеринга.

...