linux dash 全局变量,在Django模板中定义“全局变量”

我正在做类似的事情:

{% extends 'base.html' %}

{% url myapp.views.dashboard object as object_url %}

{% block sidebar %}

... {{ object_url }} ...

{% endblock %}

{% block content %}

... {{ object_url }} ...

{% endblock %}

Django文档说url templatetag可以在上下文中定义变量,但是在以下代码块中我没有得到object_url的任何值。

如果我将url templatetag放在每个块的开头,则可以,但是我不想"重复自己"。

有人知道更好的解决方案吗?

如果URL是特定于视图的,则可以从视图传递URL。如果URL在模板中需要真正是全局的,则可以将其放在上下文处理器中:

def object_url(request):

return {'object_url': reverse('myapp.views.dashboard')}

嗯,许多视图使用此变量,但不是全部。 另外,我对我的自定义templatetags定义的另一种变量使用相同的模式。 上面的情况只是简化了,所以我认为不适合采用您的解决方案。

即使未在每个模板中都使用它,将其放入上下文处理器也不会造成任何伤害……除非它当然进行数据库查找,否则在这种情况下会影响站点性能。

看起来以前已经回答过,但是还有另一种选择。使用上下文处理器来跟踪从模板外部定义的内容是一回事,但是有时您想计算两次循环经过的次数或类似的次数。还有另一种方法:

class GlobalVariable(object):

def __init__(self, varname, varval):

self.varname = varname

self.varval = varval

def name(self):

return self.varname

def value(self):

return self.varval

def set(self, newval):

self.varval = newval

class GlobalVariableSetNode(template.Node):

def __init__(self, varname, varval):

self.varname = varname

self.varval = varval

def render(self, context):

gv = context.get(self.varname, None)

if gv:

gv.set(self.varval)

else:

gv = context[self.varname] = GlobalVariable(

self.varname, self.varval)

return ''

def setglobal(parser, token):

try:

tag_name, varname, varval = token.contents.split(None, 2)

except ValueError:

raise template.TemplateSyntaxError(

"%r tag requires 2 arguments" % token.contents.split()[0])

return GlobalVariableSetNode(varname, varval)

register.tag('setglobal', setglobal)

class GlobalVariableGetNode(template.Node):

def __init__(self, varname):

self.varname = varname

def render(self, context):

try:

return context[self.varname].value()

except AttributeError:

return ''

def getglobal(parser, token):

try:

tag_name, varname = token.contents.split(None, 1)

except ValueError:

raise template.TemplateSyntaxError(

"%r tag requires arguments" % token.contents.split()[0])

return GlobalVariableGetNode(varname)

register.tag('getglobal', getglobal)

class GlobalVariableIncrementNode(template.Node):

def __init__(self, varname):

self.varname = varname

def render(self, context):

gv = context.get(self.varname, None)

if gv is None:

return ''

gv.set(int(gv.value()) + 1)

return ''

def incrementglobal(parser, token):

try:

tag_name, varname = token.contents.split(None, 1)

except ValueError:

raise template.TemplateSyntaxError(

"%r tag requires arguments" % token.contents.split()[0])

return GlobalVariableIncrementNode(varname)

register.tag('incrementglobal', incrementglobal)

这使您可以在这样的模板中使用它:

{% setglobal ii 0 %}

...

{% for ... %}

{% incrementglobal ii %}

current={% getglobal ii %}

{% endfor %}

...

{% for ... %}

{% incrementglobal ii %}

current={% getglobal ii %}

{% endfor %}

...

total of 2 loops={% getglobal ii %}

...

{% setglobal ii 0 %}

...

do something else now that {% getglobal ii %} is back to 0

您可以编写一个自定义模板标签:

@register.simple_tag(takes_context=True)

def set_global_context(context, key, value):

"""

Sets a value to the global template context, so it can

be accessible across blocks.

Note that the block where the global context variable is set must appear

before the other blocks using the variable IN THE BASE TEMPLATE.  The order

of the blocks in the extending template is not important.

Usage::

{% extends 'base.html' %}

{% block first %}

{% set_global_context 'foo' 'bar' %}

{% endblock %}

{% block second %}

{{ foo }}

{% endblock %}

"""

context.dicts[0][key] = value

return ''

我自己使用了这种方法,它对于代码和可读性非常有用。 在模板中随机编辑的全局变量很难调试。 使用模板创建状态机可以将逻辑保持在一个地方,这有很多好处。

在每个继承的模板中,不执行块重新定义之外的任何代码。因此,在您的示例中,您必须在每个块内调用{% url %}标记或使用上下文处理器来设置"全局"变量。

好吧,这是对模板继承的滥用,但是您可以使用{{block.super}}将object_url放入您的块中。

换句话说,在您的中级模板中执行以下操作:

{% block sidebar %}{{ object_url }}{% endblock %}

{% block content %}{{ object_url }}{% endblock %}

然后在您的块模板中使用:

{% block sidebar %}

... {{ block.super }}...

{% endblock %}

这不是一个好主意,因为它阻止您将{{ object_url }}以外的任何内容放入块中...但是它可以工作。只是不要告诉任何人您是从我这里得到的!

我个人应该补充一点,我更喜欢露骨并在每个模板中进行加载。 使我更容易准确地查看数据的来源。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值