Django Forms and Bootstrap - CSS and <divs> Classes

I am using Twitter Bootstrap with Django to render forms.

Bootstrap can pretty well format your forms - provided you have the CSS classes that it expects.

However, my problem is that the forms generated by Django {{ form.as_p }} not render well with Bootstrap, since they do not have these classes.

For example, the output from Django:

  <form class="horizontal-form" action="/contact/" method="post"> <div style='display:none'> <input type='hidden' name='csrfmiddlewaretoken' value='26c39ab41e38cf6061367750ea8c2ea8'/> </div> <p><label for="id_name">Name:</label> <input id="id_name" type="text" name="name" value="FOOBAR" maxlength="20" /></p> <p><label for="id_directory">Directory:</label> <input id="id_directory" type="text" name="directory" value="FOOBAR" maxlength="60" /></p> <p><label for="id_comment">Comment:</label> <textarea id="id_comment" rows="10" cols="40" name="comment">Lorem ipsum dolor sic amet.</textarea></p> <p> <label for="id_server">Server:</label> <select name="server" id="id_server"> <option value="">---------</option> <option value="1" selected="selected">sydeqexcd01.au.db.com</option> <option value="2">server1</option> <option value="3">server2</option> <option value="4">server3</option> </select> </p> <input type="submit" value="Submit" /> </form> 

From what I can tell, Bootstrap requires that your forms have <fieldset class="control-group"> , each <label> has class="control-label" , and each <input> enclosed in a <div> :

 <fieldset class="control-group"> <label class="control-label" for="input01">Text input</label> <div class="controls"> <input type="text" class="xlarge" name="input01"> <p class="help-text">Help text here. Be sure to fill this out like so, or else!</p> </div> </fieldset> 

However, adding custom CSS labels to each form field in Django is pretty painful:

Add class to Django label_tag () output

Is there a more reasonable way to use {{ form.as_p }} , or iterate through fields, without having to manually specify something, or with a whole bunch of hacker attacks?

Hooray Victor

+65
css django twitter-bootstrap
Dec 12 '11 at 12:37
source share
11 answers

I like to use "django-crispy-forms" , which is the successor to django-uni-form. This is a great API and has great support for Bootstrap.

I use template filters to quickly migrate old code and quick forms and template tags when I need more control over the rendering.

+47
Apr 02 2018-12-12T00:
source share

Here 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> 
+52
Aug 28 '12 at 7:23
source share

If django-crispy-forms cannot be used (for example, when the template processes each form field separately), jcmrgo's answer is the only way. Based on his answer, here is a solution for Bootstrap 3 (leaving its version for Boostrap 2) and with setting up field classes inside the template . Although field classes are not accessible from a template with the standard Django library (which leads to additional forms or template tags in other solutions), here is a solution that sets the correct classes to field tags without the need for 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 requires django-widget-tweaks and widget_tweaks added to INSTALLED_APPS .

+38
Dec 01 '14 at 23:18
source share

You can 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 %} 
+10
Dec 12 '11 at 12:56 on
source share

To add CSS attributes to Django generated forms, just use the following code in your forms.

 Recepient = forms.ChoiceField(label=u'Recepient', widget=forms.Select(attrs={'id':'combobox'})) 

It produces the following HTML code:

 <label for="id_Recepient">Recepient</label> <select id="combobox" name="Recepient"> 
+8
Jul 25 '14 at 10:44
source share
+4
Apr 10 2018-12-12T00:
source share

For example, you can create a class that defines attributes the way you want, and simply name it accordingly.

 class ContactForm(ModelForm): class Meta: model = Contact created = MyDatePicker() class Uniform(forms): def __init__(self, *args, **kwargs): attrs = kwargs.pop("attrs",{}) attrs["class"] = "span3" kwargs["attrs"] = attrs super(Uniform, self).__init__(*args, **kwargs) class MyDatePicker(Uniform,forms.DateInput) def __init__(self, *args, **kwargs): attrs = kwargs.pop("attrs",{}) attrs["class"] = "datepick" attrs["id"] =kwargs.get('datetag', '') kwargs["attrs"] = attrs super(MyDatePicker, self).__init__(*args, **kwargs) 
+3
Jun 13 '12 at 4:13
source share

Bootstrap style forms with <div> , not <p> s. So, if you want it to look beautiful, you need to go to the start path 100% IMHO. And here is my preferred way to do this:

Use the django-bootstrap3 app. Example:

 {% load bootstrap3 %} <form class="signup form-horizontal" id="signup_form" method="post" action="{% url 'account_signup' %}"> {% csrf_token %} {% bootstrap_form form layout="horizontal" %} {% buttons submit='Sign Up &raquo;' reset='Reset Form' layout='horizontal' %}{% endbuttons %} </form> 

Note the class attribute horizontal in 1) 2) the layout of bootstrap_form and 3) the layout of the buttons.

+3
May 10 '16 at 2:41
source share

Here is my version using django_tweaks with the best result. I find render_field easier to use than adding filters. I also added bootstrap-formatted warnings and turned off the navigator check (with the update). I'm relatively new to Django, so feel free to comment if you find any non-meaning

 <form class="large" method="post" action="/suscript/" novalidate> {% csrf_token %} <fieldset> <legend>{{ title }}</legend> {% for field in form %} <div class="control-group {%if field.errors %}error{%endif%}"> <div class="input-group controls"> <label class="input-group-addon control-label" id="{{field.label|safe}}">{{ field.label }}</label> {% render_field field type="text" class="form-control" placeholder="" aria-describedby="field.label|safe" %} </div> {% for error in field.errors %} <div class="alert alert-danger"> <strong>{{ error|escape }}</strong> </div> {% endfor %} {% if field.help_text %} <p class="help-inline">{{ field.help_text|safe }}</p> {% endif %} </div> {% endfor %} </fieldset> <div class="form-actions"> <button type="submit" class="btn btn-primary" >Submit</button> </div> </form> 
+3
Jun 07 '17 at 19:40
source share

The easiest and easiest way is to define your own base class that extends the Django Form class and override its as_p method for output in Bootstrap format. Then change your forms inherit from the new Form class instead of Django.

+2
Dec 12 '11 at 12:40
source share

besides what other friends said, I would recommend using 'django-widget-tweaks'.

The answer will be something like this:

 {% for field in form %} <label for="{{ field.label }}">{{ field.label }}</label> {{ field|add_class:"form-control" }} <span class="error-block">{{ field.errors }}</span> {% endfor %} 
0
Aug 22 '19 at 10:48
source share



All Articles