在 Django 中的表单标签中解析 forloop.counter

Posted

技术标签:

【中文标题】在 Django 中的表单标签中解析 forloop.counter【英文标题】:Parsing forloop.counter in form's label in Django 【发布时间】:2015-09-16 18:24:23 【问题描述】:

我没有成功尝试使我通过循环生成的某些表单的标签依赖于forloop.counter。这是我到目前为止所拥有的:

% for field in form %

% formfield field with label="blablabla  forloop.counter " %

% endfor %

这将返回正确的形式,但 forloop.counter 在标签中按原样显示,而不是被其值替换。

我做错了什么?我在 Django 代码中到处都能看到这种结构,例如在https://docs.djangoproject.com/en/1.4/intro/tutorial04/

<h1> poll.question </h1>

% if error_message %<p><strong> error_message </strong></p>% endif %

<form action="/polls/ poll.id /vote/" method="post">
% csrf_token %
% for choice in poll.choice_set.all %
    <input type="radio" name="choice" id="choice forloop.counter " value=" choice.id " />
    <label for="choice forloop.counter "> choice.choice </label><br />
% endfor %
<input type="submit" value="Vote" />
</form>

除了上面示例中的 id 之外,是什么使表单的标签无法将 forloop.counter 解析为字符串?

【问题讨论】:

那根本不一样。在该示例中,您没有看到在 inside 另一个 Django 标记中使用了 Django 变量语法。 @Daniel Roseman:没错,感谢您指出。我将尝试了解更多关于在标签中使用 Django 变量的信息。 【参考方案1】:

我们不能在另一个 Django 标签 % % 中使用 Django 变量

Django 在其文档中没有在任何地方的模板标签% % 中使用 。到处都是单独使用的。

例如:

以下2个代码sn-ps都有效。

% firstof var1 var2 var3 % # valid
<li>  some_variable  </li> # valid

但是,这段代码 sn-p 无效。

% firstof var1 var2 some_var % # invalid

那么可以做什么呢?

我们知道已经存在于模板中的变量可以在模板标签% % 中赋值。所以,如果我们事先计算一个变量my_label,那么我们可以直接在模板标签中分配这个变量。

% formfield field with label=my_label % # our target

所以,我们需要计算"blablabla&lt;x&gt;" 的值,其中xforloop.counter 的值,并将其存储在变量my_label 中。

计算 label 值并将其存储在单独的变量中

要将值存储在变量中,我们可以使用内置的with 模板标签。

我们可能很想使用下面的行来计算my_label 变量,但这会导致错误,因为我们再次在模板标签中使用相同的变量语法。

% with my_label="blablablaforloop.counter" % # invalid

因此,我们现在需要以不同的方式解决问题。我们必须将choiceforloop.counter 的值连接起来以得到blablabla1blablabla2 等等,并且我们知道存在一个模板过滤器add,它将参数添加到值中。我们可以使用这个过滤器。

所以,我们试试下面的代码。

% with my_label="blablabla"|add:forloop.counter % # will still not work 

但这仍然不能解决我们的问题。一个空字符串'' 将被分配给my_label 变量,因为我们试图将一个整数forloop.counter 与一个字符串"blablabla" 相加。在将整数与字符串相加时,将引发错误,如果出现错误,Django 将为其分配一个空字符串。

根据add filter 上的文档:

此过滤器将首先尝试将两个值强制转换为整数。如果这 失败,无论如何它都会尝试将这些值相加。这将起作用 在某些数据类型(字符串、列表等)上失败,而在其他数据类型上失败。如果它 失败,结果将是一个空字符串。

所以,我们需要先将forloop.counter 的值转换为字符串,并将其存储在变量counter_value 中。这可以使用stringformat 内置模板过滤器来完成。然后我们可以使用add 过滤器。

% with counter_value=forloop.counter|stringformat:"s" %  # assign counter value to a variable
% with my_label="blablabla"|add:counter_value % # compute value of 'my_label'

现在,我们拥有my_label 的值,我们可以使用它来获得所需的结果。

% formfield field with label=my_label % # use your label variable here

最终代码:

% for field in form %

    % with counter_value=forloop.counter|stringformat:"s" % 
    % with my_label="blablabla"|add:counter_value % 
    % formfield field with label=my_label %
    % endwith %
    % endwith %

% endfor %

注意:我正在尝试稍微不同的代码版本,而不是最初发布的答案(如下所示),这不会导致 OP 出现错误。感谢@Daniel 纠正错误。

之前发布的答案,即下面的代码不能作为在 Django 标记 % % 中工作,我们不能放入

# this initially posted code won't work
% formfield field with label='blablabla  forloop.counter|stringformat:"s" ' %

【讨论】:

好的,感谢您的跟进。 Django 版本:1.8.4。问题也可能来自 otree。我也会问他们。同时,感谢您提出任何其他建议。 目前不在我的机器上,但我一定会在回到它后尝试。 恐怕我目前没有可能的原因来解释为什么会发生这种情况。 不用担心,感谢您的尝试。我在github.com/oTree-org/otree-docs/issues/13 的 otree 的 Github 存储库的问题队列上发布了一个相关问题。希望我能弄明白,然后回来在这里分享答案。 这不可能永远有效,我不知道为什么 Rahul 说它应该。

以上是关于在 Django 中的表单标签中解析 forloop.counter的主要内容,如果未能解决你的问题,请参考以下文章

删除 Django Crispy 表单中的标签

Django-jQuery 和标签?

Django中Form表单之字段详解

如何将类添加到 Django 表单中的字段标记

将自定义html添加到django中的choicefield标签

Django 之 form表单