Grouping Django Form Fields

Let's say I have a form with 20 fields, and I want to put 10 of these fields (group1) in a specific div environment and the other 10 fields (group2) in another div environment. Sort of:

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

Any ideas how I could do this, field iteration? More generally, I would like to be able to do this with many different div environments and sets of form fields.

+6
source share
2 answers

Any logical way to group fields will work ... let's say you have a method in your form that returns form fields that you explicitly group?

To preserve typing, perhaps a specific naming scheme for a field prefix?

 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 in a field that you can filter?

 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 can also use the rearrange 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 %} 
+13
source

Here is the relevant SO question: Django and Fieldsets on Modelform , although this seems a bit redundant for what I want to accomplish. Also, here is one of the possible hacks, although I'm curious to see how Django experts solve this problem.

(0) Define a python field set object that is iterable so that we can iterate over it in the 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 %} 

Please note that you can replace the fieldset tag with a div tag to solve my specific issue.

+++ Most of this answer is extracted from Michael Kowalczyk on this blog . +++

+4
source

Source: https://habr.com/ru/post/914428/


All Articles