Django Forms and Bootstrap - CSS classes and <divs>
This is what I came up with:
<form class="form-horizontal" method="post">{% csrf_token %}
<fieldset>
<legend>{{ title }}</legend>
{% for field in form %}
{% if field.errors %}
<div class="control-group error">
<label class="control-label">{{ field.label }}</label>
<div class="controls">{{ field }}
<span class="help-inline">
{% for error in field.errors %}{{ error }}{% endfor %}
</span>
</div>
</div>
{% else %}
<div class="control-group">
<label class="control-label">{{ field.label }}</label>
<div class="controls">{{ field }}
{% if field.help_text %}
<p class="help-inline"><small>{{ field.help_text }}</small></p>
{% endif %}
</div>
</div>
{% endif %}
{% endfor %}
</fieldset>
<div class="form-actions">
<button type="submit" class="btn btn-primary" >Submit</button>
</div>
</form>
You could do something like this:
{% for field in form %}
<fieldset class="control-group">
<label class="control-label" for="id_{{ field.name }}">{{ field.label }}</label>
<div class="controls">
{{ field }}
<p class="help-text">{{ field.help_text }} </p>
</div>
</fieldset>
{% endfor %}
When django-crispy-forms
cannot be used (e.g. when the template treats individually each field of the form), jcmrgo's answer is the only way to go. Based on his answer, here is a solution for Bootstrap 3 (leaving his version for Boostrap 2), and with adjustment of field classes inside the template. While field classes are not reachable from within the template with Django's standard library (which leads to that extra forms or template tags in other solutions), here is a solution that sets the right classes to field tags without having to code outside the template:
{% load i18n widget_tweaks %}
<form class="form-horizontal" role="form" action="." method="post">
{% csrf_token %}
{% for field in form %}
{% if field.errors %}
<div class="form-group has-error">
<label class="col-sm-2 control-label" for="id_{{ field.name }}">{{ field.label }}</label>
<div class="col-sm-10">
{{ field|attr:"class:form-control" }}
<span class="help-block">
{% for error in field.errors %}{{ error }}{% endfor %}
</span>
</div>
</div>
{% else %}
<div class="form-group">
<label class="col-sm-2 control-label" for="id_{{ field.name }}">{{ field.label }}</label>
<div class="col-sm-10">
{{ field|attr:"class:form-control" }}
{% if field.help_text %}
<p class="help-block"><small>{{ field.help_text }}</small></p>
{% endif %}
</div>
</div>
{% endif %}
{% endfor %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary">{% trans "Submit" %}</button>
</div>
</div>
</form>
This needs django-widget-tweaks
installed and widget_tweaks
added to INSTALLED_APPS
.
I like to use "django-crispy-forms" which is the successor to django-uni-form. It's a great little API and has great support for Bootstrap.
I tend to use the template filters for quickly porting old code and quick forms, and the template tags when I need more control over the rendering.