14

假设我有一个包含 20 个字段的表单,我想将其中的 10 个字段(group1)放在特定的 div 环境中,将其他 10 个字段(group2)放在不同的 div 环境中。就像是:

<div class="class1">
{% for field in form.group1 %}
            {{ field.label}}: {{ field }}
{% endfor %}
</div>

<div class="class2">
{% for field in form.group2 %}
            {{ field.label}}: {{ field }}
{% endfor %}
</div>

有什么想法可以通过遍历字段来实现这一点吗?更一般地说,我希望能够使用许多不同的 div 环境和表单字段集来做到这一点。

4

3 回答 3

22

对字段进行分组的任何合乎逻辑的方法都可以使用...假设您的表单上有一个方法可以返回您明确分组的表单字段?

为了节省打字,也许是某个字段前缀命名方案?

class MyForm(forms.Form):
    group1_field = forms.CharField()
    group1_field = forms.CharField()
    group2_field = forms.CharField()
    group2_field = forms.CharField()

   def group1(self):
        return [self[name] for name in filter(lambda x: x.startswith('group1_'), self.fields.values()]

也许在您可以过滤的字段上设置一个属性?

class MyForm(forms.Form):
    field = forms.CharField()
    field.group = 1

    field2 = forms.CharField()
    field2.group = 2

    def group1(self):
        return filter(lambda x: x.group == 1, self.fields.values())

    def group2(self):
        return filter(lambda x: x.group == 2, self.fields.values())

如果您设置了这些属性,您也可以使用重组标签。

{% regroup form.fields by group as field_group %}
{% for group in field_group %}
<div class="group_{{ group.grouper }}">
  {% for field in group.list %}
    {{ field }}
  {% endfor %}
</div>
{% endfor %}
于 2012-04-28T21:39:00.793 回答
5

这是一个相关的 SO 问题:Django and Fieldsets on Modelform,尽管这对于我想要完成的事情来说似乎有点矫枉过正。此外,这是一种可能的 hack,尽管我很想知道 Django 专家是如何解决这个问题的。

(0) 定义一个可迭代的 python 字段集对象,以便我们可以在 django 模板中对其进行迭代:

from django.forms.forms import BoundField

class FieldSet(object):
    def __init__(self,form,fields,legend='',cls=None):
        self.form = form
        self.legend = legend
        self.fields = fields
        self.cls = cls

    def __iter__(self):
        for name in self.fields:
            field = self.form.fields[name]
            yield BoundField(self.form, field, name)

(1) 在视图中使用:

fieldsets = (FieldSet(form_object, ('field_name1','field_name2'),
                        legend='Div env 1',
                        cls="class1"),
             FieldSet(form_object, ('field_name3','field_name4'), 
                        legend="Div env 2",
                        cls="class2"))

return render_to_response('my_form.html',
                          {'form': form_object,'fieldsets':fieldsets},
                          context_instance=RequestContext(request))

(2) 现在在模板中做:

{% for set in fieldsets %}
    <fieldset{% if set.cls %} class="{{ set.cls }}"{% endif %}>
      <legend>{{ set.legend }}</legend>
      {% for field in set %}
          {{ field.label}} : {{ field }}
      {% endfor %}
    </fieldset>
{% endfor %}

请注意,可以用标签替换fieldset标签div来解决我的具体问题。

+++ 这个答案的大部分内容来自Michael Kowalchik 的这篇博文。+++

于 2012-04-28T21:31:05.883 回答
3

我终于能够将@Yuji'Tomita'Tomitas regroup -template -tag-solution 带入工作(请参阅@Yuji'Tomita'Tomitas 回答中的评论以了解困难)。我认为这确实是一种对字段进行分组的好方法!

解决方案是通过group访问field返回属性的字段属性重新组合BoundFields。最小的例子:

forms.py 中

class TestForm(Form):
    a = IntegerField()
    a.group = 1
    b = IntegerField()
    b.group = 1
    c = IntegerField()
    c.group = 2
    d = IntegerField()
    d.group = 2

在模板中:

<form>
  {% csrf_token %}
  {% regroup form by field.group as field_groups %}
  {% for field_group in field_groups %}
    {{field_group.grouper}}
    {% for field in field_group.list %}
      {{field}}
    {% endfor %}
  {% endfor %}
</form>
于 2018-04-05T12:54:39.560 回答