Django Forms and Bootstrap - CSS classes and divs
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.
Setting css class to field in form depending of it's type
you can use the django form that is inherited from modelform to define specific css class to the form fields.
for instance,
models.py file:
class Post(models.Model):
title=models.CharField(max_length=254)
text=models.TextField()
forms.py file
from . import models
class PostForm(forms.ModelForms):
class Meta():
model=models.Post
fields='__all__'
widgets={
'title':forms.TextInput(attrs={'class':'textinputclass'}), #--->> you can use this textinputclass as the css class in your css file to style the title field of your forms.
'text':forms.Textarea(attrs={'class':'content'})
}
now in your static>css>yourcss.css you can access the class that we defined above as normal css class.
.content{
font-size:15px;
}
How can I add bootstrap styles to my django form?
To add bootstrap styling to your form, you're going to need to paste this code somewhere between your tags for the CSS;
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
And this for the JavaScript;
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
This will apply some styling to your form.
Once you've done this, you'll have to use the classes that are specified on the BootStrap documentation that you can find here if you want to change the styling: https://getbootstrap.com/docs/4.1/components/forms/
This should give you the styling that you want although you may want to add a bit of your own additionally to get exactly what you're after.
How to add CSS classes to Django Built-in forms
With the objective of not re-writing the fields, I found out that I could simply update the Widget:
class PasswordChangeCustomForm(PasswordChangeForm):
def __init__(self, user, *args, **kwargs):
super(PasswordChangeCustomForm, self).__init__(user, *args, **kwargs)
self.fields['old_password'].widget.attrs.update({'class': 'form-control'})
self.fields['new_password1'].widget.attrs.update({'class': 'form-control'})
self.fields['new_password2'].widget.attrs.update({'class': 'form-control'})
Particularly useful for Bootstrap (where all fields need the class form-control
) is the answer from @daniel-roseman:
class PasswordChangeCustomForm(PasswordChangeForm):
def __init__(self, user, *args, **kwargs):
super(PasswordChangeCustomForm, self).__init__(user,*args, **kwargs)
for field in self.fields:
self.fields[field].widget.attrs['class'] = 'form-control'
Bootstrap classes to Django UpdateView
You can add class with django-widget-tweaks, but you can't add class directly to form you should use the filter render_field for customizing fields of form.
In your settings.py
INSTALLED_APPS = [
...
'widget_tweaks',
...
]
In your template you can put like this
{% load widget_tweaks %}
<form>
{% csrf_token %}
{% for field in form %}
{% if field.errors %}
<div class="form-group">
<label for="id_{{ field.name }}">{{ field.label }}:</label>
{% render_field field class="form-control is-invalid" %}
<div class="invalid-feedback">
<ul>
{% for error in field.errors %}
<li>{{error|escape}}</li>
{% endfor %}
</ul>
</div>
</div>
{% else %}
<div class="form-group">
<label for="id_{{ field.name }}">{{ field.label }}:</label>
{% render_field field class="form-control" %}
</div>
{% endif %}
{% endfor %}
</form>
Another easier way is to use django-crispy-forms, which adds bootstrap styles more automatically.
In your settings.py
INSTALLED_APPS = (
...
'crispy_forms',
)
You can render the entire form
{% load crispy_forms_tags %}
{% my_form|crispy %}
Or a field
{% load crispy_forms_tags %}
{{my_form.field|as_crispy_field}}
If you simply want to add a class to the form you can do this:
<form class="my_bootstrap_class">
{% csrf_token %}
{% for field in form %}
...
{% endfor %}
</form>
Define css class in django Forms
Answered my own question. Sigh
http://docs.djangoproject.com/en/dev/ref/forms/widgets/#django.forms.Widget.attrs
I didn't realize it was passed into the widget constructor.
Related Topics
Browser Support for CSS :First-Child and :Last-Child
How to Check Which CSS Styles Are Being Used or Not Used on a Web Page
Styling Elements with a Dot (.) in the Class Name
Vertical Align Table-Cell Don't Work with Position Absolute
Div with Cut Out Edges, Border and Transparent Background
Image Scaling by CSS: Is There a Webkit Alternative for -Moz-Crisp-Edges
First-Child Full-Width in Flexbox
CSS Select First Element with a Certain Class
How to Center Content and Make the Background Cover the Full Column When Using CSS Grid
Can You Target an Element with CSS Only If 2 Classes Are Present
Can One CSS File Take Priority Over Another CSS File
Inner Border Over Images with CSS
How to Use Camelcase in CSS Class Names
Turning Off Twitter Bootstrap Navbar Transition Animation
Order of Prioritization When Using Multiple Contradictory CSS Files
How to Use a CSS Wildcard in the Middle of an Attribute Selector