Django 如何在模板代码中设置变量的值?

Django 如何在模板代码中设置变量的值?,django,django-templates,Django,Django Templates,假设我有一个模板 <html> <div>Hello {{name}}!</div> </html> 你好{{name}}! 在测试时,定义变量的值而不涉及调用此模板的python代码将非常有用。所以我在找这样的东西 {% set name="World" %} <html> <div>Hello {{name}}!</div> </html> {%set name=“World”%

假设我有一个模板

<html>
<div>Hello {{name}}!</div>
</html>

你好{{name}}!
在测试时,定义变量的值而不涉及调用此模板的python代码将非常有用。所以我在找这样的东西

{% set name="World" %}     
<html>
<div>Hello {{name}}!</div>
</html>
{%set name=“World”%}
你好{{name}}!
Django中是否存在类似的内容?

您可以使用模板标记

{% with name="World" %}     
<html>
<div>Hello {{name}}!</div>
</html>
{% endwith %}
{%with name=“World”%}
你好{{name}}!
{%endwith%}

有一些像约翰描述的把戏;但是,Django的模板语言design不支持设置变量(请参见中的“哲学”框)。

因此,建议通过触摸Python代码来更改任何变量。

不需要将所有内容都放在“with”块中的另一种方法是创建一个自定义标记,将新变量添加到上下文中。例如:

class SetVarNode(template.Node):
    def __init__(self, new_val, var_name):
        self.new_val = new_val
        self.var_name = var_name
    def render(self, context):
        context[self.var_name] = self.new_val
        return ''

import re
@register.tag
def setvar(parser,token):
    # This version uses a regular expression to parse tag contents.
    try:
        # Splitting by None == splitting by spaces.
        tag_name, arg = token.contents.split(None, 1)
    except ValueError:
        raise template.TemplateSyntaxError, "%r tag requires arguments" % token.contents.split()[0]
    m = re.search(r'(.*?) as (\w+)', arg)
    if not m:
        raise template.TemplateSyntaxError, "%r tag had invalid arguments" % tag_name
    new_val, var_name = m.groups()
    if not (new_val[0] == new_val[-1] and new_val[0] in ('"', "'")):
        raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name
    return SetVarNode(new_val[1:-1], var_name)
这将允许您在模板中编写类似的内容:

{% setvar "a string" as new_template_var %}

请注意,其中大部分是

这通常不是一个好主意。在python中执行所有逻辑,并将数据传递给模板进行显示。模板应该尽可能简单,以确保从事设计的人员能够专注于设计,而不是担心逻辑


举个例子,如果您需要模板中的一些派生信息,最好将其放入python代码中的变量中,然后将其传递给模板。

最好的解决方案是编写一个自定义的
赋值标记。此解决方案比使用带有
标记的
更干净,因为它在逻辑和样式之间实现了非常清晰的分离

首先创建一个模板标记文件(例如,
appname/templatetags/hello_world.py
):

现在,您可以在模板中使用
get\u address
template标记:

{% load hello_world %}

{% get_addressee as addressee %}

<html>
    <body>
        <h1>hello {{addressee}}</h1>
    </body>
</html>
{%load hello\u world%}
{%get_收件人作为收件人%}
你好{{收件人}
创建模板标记: 该应用程序应该包含一个
templatetags
目录,与
models.py
views.py
等处于同一级别。如果这个目录不存在,请创建它-不要忘记
\uuu init\uuuuuuuuuuuuuuuuupy
文件,以确保该目录被视为Python包

使用以下代码在templatetags目录中创建一个名为
define_action.py
的文件: 注意:开发服务器不会自动重新启动。添加
templatetags
模块后,您需要重新启动服务器,然后才能使用模板中的标记或过滤器


然后,您可以在模板中为上下文指定值,如下所示:
在模板中,您可以这样做:

{% jump_link as name %}
{% for obj in name %}
    <div>{{obj.helo}} - {{obj.how}}</div>
{% endfor %}
@register.assignment_tag
def jump_link():
    listArr = []
    for i in range(5):
        listArr.append({"helo" : i,"how" : i})
    return listArr
也许在2009年的时候,这不是一个选择

<html>
<div>Hello {{name|default:"World"}}!</div>
</html>

你好{{name |默认值:“World”}!
使用


我不能暗示这本书第一段的代码。也许模板语言不赞成旧格式

谢谢你的指点。从设计师的角度来看,在设计页面时,快速设置变量以测试页面的各种状态有时更容易。不建议在运行的代码中使用这种做法。django1.0接受“with”标记。所以看起来他们终于在修正他们的哲学:)。事实上,“with”标签只是用于别名。这可能会对性能(以及可读性)产生巨大影响,但在传统编程术语中,这并不是真正设置变量。但您可以在with中更改变量的值吗?您似乎无法在with子句中声明容器(我尝试了列表和元组)。如果您需要声明列表,请使用make_list。Jinja说它是{%set myvar=value%}为什么它在django中不起作用?@holms因为django不使用Jinja:-)把变量分配给上下文中的其他变量怎么样?另一方面:允许模板在不检查上下文变量是否存在的情况下任意分配上下文变量可能会带来安全隐患。在我看来,一种更明智的方法是在尝试分配变量之前检查变量的上下文:if context.get(self.var_name):raise discitiousoperation(“尝试从上下文中已经存在的模板分配变量”),我必须说这就是我要找的!它也可以与一起使用:
{%with state=form.state.value |默认值:other_context_variable%}
而不是
other_context_variable
我们也可以使用任何
'string_value'
但它会打印出来,我需要在循环返回旧值后保存它以备以后使用:(在最新版本中,您似乎可以使用simple_标记而不是assignment_标记(这对我很有用)。这个解决方案的问题是,您似乎无法覆盖值。如果您想使用此技术设置列表而不仅仅是一个值,请选中此项:如果您将变量设置为整数,并且希望将其递增(例如),则需要使用
添加
{%define counter | add:1作为counter%}
。其他操作也是如此。对于使用较新Django版本的用户,它现在被称为simple_tag!节省时间找出代码中无法识别“register..”的原因。。。
{% jump_link as name %}
{% for obj in name %}
    <div>{{obj.helo}} - {{obj.how}}</div>
{% endfor %}
@register.assignment_tag
def jump_link():
    listArr = []
    for i in range(5):
        listArr.append({"helo" : i,"how" : i})
    return listArr
<html>
<div>Hello {{name|default:"World"}}!</div>
</html>
{% with total=business.employees.count %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}