在模板标记中获取模板名称(Django)

2024-04-29 13:50:50 发布

您现在位置:Python中文网/ 问答频道 /正文

是否有方法在模板标记中获取模板名称(正在分析)? 我读了搜索,什么也没找到,只有这篇上一篇文章 Getting the template name in django template

这对我没有多大帮助,因为答案依赖于settings.DEBUG是否为true,在我的情况下,这是不可能的。

我真的不知道从哪里开始,所以欢迎任何建议:)

编辑

所以基本上我想要的是创建一个可插入的标记,当呈现它时,它会检查一个标记对象,这将是标记对象的源

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

如果有一个标记对象,那么它会显示所有的插件对象,如果没有,它会创建一个与模板标记和模板名称中提供的名称唯一的标记对象,如果无法获取模板名称,那么我想我可以让它每个名称都是唯一的。对于熟悉django cms的人来说,整个标签有点像一个占位符


Tags: the对象django方法namein标记名称
2条回答

在源代码中,虽然^{}对象可以访问模板名(通过.name),但此值从未传递给Parser对象,因此不能用于模板标记。

有多种方法可以使模板名称对模板本身可用(通过将其添加到上下文中),但不在模板标记内。

正如丹尼尔·罗斯曼在评论中提到的,如果你能详细说明你真正想要达到的目标,也许有更好的方法来实现你想要的目标。没有冒犯,但听起来可能是XY problem


出于对学术的兴趣,我急忙摆弄了一下,看是否有可能。据我所见,这是可能的,但不是没有改变或猴子补丁的django源。

注意:以下不是建议的解决方案,只是提示实际工作可能需要什么。不用于生产代码。

通过使用以下更改修改django.template.base.py,我们将.template_name属性添加到parser对象,使其可用于模板标记。

  1. Added optional arg to ^{}
  2. Added template name as extra attribute to parser
  3. Passed in the template name when calling ^{}

为了测试这一点,我定义了以下标记,它只返回大写的模板名称:

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源代码永远不是一个好的解决方案,而且在迁移到不同版本时会遇到各种各样的麻烦。

您也许可以使用上下文处理器来实现这一点,但我不确定这些处理器是否可以访问模板的名称。

接下来的工作是为您所做的呈现调用制作一个包装器。假设您当前正在执行以下操作:

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”,并用myrender替换所有的render调用。就我个人而言,我更喜欢这样,因为这使得它可以取代现有的呈现函数。

相关问题 更多 >