Django form field grouping

后端 未结 3 421
说谎
说谎 2020-12-30 09:23

Say I have a form with 20 fields, and I want to put 10 of these fields (group1) in a particular div environment and the other 10 fields (group2) in a different div environme

相关标签:
3条回答
  • 2020-12-30 10:04

    Any logical way to group fields would work... say you have a method on your form that returns form fields that you explicitly group?

    To save typing, perhaps a certain field prefix naming scheme?

    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()]
    

    Perhaps set an attribute on the field you can filter by?

    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())
    

    You could also use the regroup tag if you set these attributes.

    {% 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 %}
    
    0 讨论(0)
  • 2020-12-30 10:07

    Here's a relevant SO question: Django and Fieldsets on Modelform, though this seems a bit overkill for what I'm looking to accomplish. Also, here's one possible hack, although I'm curious to hear how Django experts solve this problem.

    (0) Define a python fieldset object that is iterable so we can iterate over it in a django template:

    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) In the view use:

    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) Now in the template do:

    {% 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 %}
    

    Note that it is possible to replace the fieldset tag with a div tag to address my specific question.

    +++ Much of this answer extracted from this blog post by Michael Kowalchik. +++

    0 讨论(0)
  • 2020-12-30 10:27

    I finally was able to bring @Yuji'Tomita'Tomitas regroup-template-tag-solution to work (see comments in @Yuji'Tomita'Tomitas answer to understand difficulties). I think this is really a nice and easy way to perfom grouping of fields!

    The solution was to regroup via group attribute of field accessing the field attribute of returned BoundFields. Minimal example:

    In 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
    

    In template:

    <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>
    
    0 讨论(0)
提交回复
热议问题