I'm trying to render a form which allows for multiple selections via checkboxes.
I've tried with django-multiselectfield (which I was already using) and the native CheckboxSelectMultiple widget.
If I have a simple form like so:
FAVORITE_COLORS_CHOICES = [
('blue', 'Blue'),
('green', 'Green'),
('black', 'Black'),
]
class SimpleForm(forms.Form):
favorite_colors = forms.MultipleChoiceField(
required=False,
widget=forms.CheckboxSelectMultiple,
choices=FAVORITE_COLORS_CHOICES,
)
And if I render with widget tweaks like so:
{% render_field form.favorite_colors %}
I get the following HTML output
<div id="id_favorite_colors">
<div>
<label for="id_favorite_colors_0">
<input class="form-control" id="id_favorite_colors_0" name="favorite_colors" placeholder="Your Name" type="checkbox" value="blue" />
Blue</label>
</div>
<div>
<label for="id_favorite_colors_1">
<input class="form-control" id="id_favorite_colors_1" name="favorite_colors" placeholder="Your Name" type="checkbox" value="green" />
Green</label>
</div>
<div>
<label for="id_favorite_colors_2">
<input class="form-control" id="id_favorite_colors_2" name="favorite_colors" placeholder="Your Name" type="checkbox" value="black" />
Black</label>
</div>
</div>
This is causing problems for the way I want to render my form. Is there any way I can force Django to output the input and then the label, so the html would be like so:
<div id="id_favorite_colors">
<div>
<input class="form-control" id="id_favorite_colors_0" name="favorite_colors" placeholder="Your Name" type="checkbox" value="blue" />
<label for="id_favorite_colors_0">Blue</label>
</div>
<div>
<input class="form-control" id="id_favorite_colors_1" name="favorite_colors" placeholder="Your Name" type="checkbox" value="green" />
<label for="id_favorite_colors_1">Green</label>
</div>
<div>
<input class="form-control" id="id_favorite_colors_2" name="favorite_colors" placeholder="Your Name" type="checkbox" value="black" />
<label for="id_favorite_colors_2">Black</label>
</div>
</div>
I haven't found an easy answer to this and most of the discussions I've found are from 10 years ago or so.
You can try this out to find if it will work for you.
Your template will look some thing like this
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="id_favorite_colors">
{% for choice in form.favorite_colors %}
<div>
<label for="id_favorite_colours_{{ forloop.counter0 }}">{{choice.choice_label}}</label>
{{ choice.tag }}
</div>
{% endfor %}
</div>
</body>
</html>
And your views.py will look like this
def simple(request):
form = SimpleForm()
# Any custom logic you want to use for the form
return render(request, "test.html", {"form":form})