Add Custom CSS Styling to Model Form Django

CSS styling in Django forms

Taken from my answer to:
How to markup form fields with <div class='field_type'> in Django

class MyForm(forms.Form):
myfield = forms.CharField(widget=forms.TextInput(attrs={'class': 'myfieldclass'}))

or

class MyForm(forms.ModelForm):
class Meta:
model = MyModel

def __init__(self, *args, **kwargs):
super(MyForm, self).__init__(*args, **kwargs)
self.fields['myfield'].widget.attrs.update({'class': 'myfieldclass'})

or

class MyForm(forms.ModelForm):
class Meta:
model = MyModel
widgets = {
'myfield': forms.TextInput(attrs={'class': 'myfieldclass'}),
}

--- EDIT ---

The above is the easiest change to make to original question's code that accomplishes what was asked. It also keeps you from repeating yourself if you reuse the form in other places; your classes or other attributes just work if you use the Django's as_table/as_ul/as_p form methods. If you need full control for a completely custom rendering, this is clearly documented

-- EDIT 2 ---

Added a newer way to specify widget and attrs for a ModelForm.

Add custom CSS styling to model form django

Try this:

forms.py

class EmailForm(forms.ModelForm):
...
subject = forms.CharField(
label = 'Subject',
max_length = 1000,
required = True,
widget = forms.TextInput(
attrs = {'class': 'summernote', 'name': 'subject'}
)
)

body = forms.CharField(
label = 'Body',
max_length = 1000,
required = True,
widget = forms.TextInput(
attrs = {'class': 'summernote', 'name': 'body'}
)
)
...

class Meta:
model = MarketingEmails
fields = ('messageid','subject','body','name', ... )

view.py

from django.shortcuts import render
from your_app_path.forms import EmailForm

def fname(request):
...
marketing = MarketingEmails.objects.get(...)

form = EmailForm(instance=marketing)
...

return render(request, 'yourview.html', { 'form': form })

yourview.html

<form action="" method="post">
{% csrf_token %}
{% for field in form %}
{{ field.label_tag }}
{{ field }}

{% if field.help_text %}
{{ field.help_text }}
{% endif %}

{% for error in field.errors %}
{{ error }}
{% endfor %}

{% endfor %}
<button type="submit" class="btn btn-primary">Submit</button>
</form>

How can I style a django form with css?

Within your template you have to just import the css file in the head tag, but do ensure you load static first.

html file:

{% load static %}

<!doctype html>
<html lang="en">
<head>
# import the css file here
<link rel="stylesheet" href="{% static 'path to css file' %}">
</head>
...
</html>

Within the css file:

# Styling the class 
.myfieldclass{
width: 30% !important;
height: 100px !important;
...
}

But please note that you don't have to import a css file since you can add the style tag in the head tag as well. For example:

<!doctype html>
<html lang="en">
<head>
<style type="text/css">
.myfieldclass{
width: 30% !important;
height: 100px !important;
...
}
</style>
</head>
...
</html>

You could apply css from the python file itself as well.

Approach from the python file.

# Custom way to set css styling on a form field in python code
def field_style():
styles_string = ' '

# List of what you want to add to style the field
styles_list = [
'width: 30% !important;',
'height: 100px !important;',
]

# Converting the list to a string
styles_string = styles_string.join(styles_list)
# or
# styles_string = ' '.join(styles_list)
return styles_string

class MyForm(forms.Form):
myfield = forms.CharField(widget=forms.TextInput(attrs={'class': 'myfieldclass', 'style': field_style()}))
# 'style': field_style() .... field_style() will return in this case 'width: 30% !important; height: 100px !important;'

Any of those should work but I do recommend doing the styling from the hmtl or css file instead.

How to style model form in django with CSS?

You are right on the point that widget provides you with an option to style your form but it will only style the field for you not the label and any class you mention in the widget should be available in the stlyesheet . you can check the link below it provides a simple example on how you can style your form.

Simple form styling

and if you want to fully style the form with labels and how it should be structured you will have to loop over the form.
below I have mentioned a simple code that illustrates how you can structure your form using django forms

<style>
.h-100{
min-height:100vh;
}
</style>

<div class="w-100 d-flex justiy-content-center align-items-center h-100" >
<form method="POST" class="row" enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
<div class="col-6 text-start"> {{field.label}} </div>
<div class="col-6"> {{field}} </div>
{% endfor %}
<button type="submit">submit</button>
</form>

i hope this helps you in your problem :)

How to add css for both label and input field in django from form.py

You don’t have to let Django unpack the form’s fields; you can do it manually if you like. Each field is available as an attribute of the form using {{ form.name_of_field }}, and in a Django template, will be rendered appropriately. As you unpack the form with form.as_p you can add your css classes like :

<p><label class="my-classes" for="{{ form.name.id_for_label }}">Name:</label>
{{ form.name }}</p>
<p><label class="my-classes" for="{{ form.address.id_for_label }}">Address:</label>
{{ form.address}}</p>
<p><label class="my-classes" for="{{ form.mobile.id_for_label }}">Mobile:</label>
{{ form.mobile}}</p>

[docs]

Applying css styles to form items in Django

This is easy to do in class based forms. Example from my project where form-control is a css class.

from django.forms import ModelForm, TextInput

class ServerForm(ModelForm):

class Meta:
model = Server
fields = ['name', 'ip', 'port']
widgets = {
'name': TextInput(attrs={'class': 'form-control'}),
'ip': TextInput(attrs={'class': "form-control"}),
'port': TextInput(attrs={'class': 'form-control'}),
}

Then the template I have looks like:

{% for field in form %}
<div class="form-group">
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}

Which generates

<form method="POST">
<input type="hidden" name="csrfmiddlewaretoken" value="xxxxxx">
<div class="form-group">
<label for="id_name">Name:</label>
<input class="form-control" id="id_name" maxlength="64" name="name" type="text">
</div>
<div class="form-group">
<label for="id_ip">Ip:</label>
<input class="form-control" id="id_ip" maxlength="20" name="ip" type="text">
</div>
<div class="form-group">
<label for="id_port">Port:</label> <input class="form-control" id="id_port" name="port" type="text">
</div>
<div class="form-group">
<button type="submit" class="save btn btn-default">Add/Edit Server</button>
</div>
</form>

The key is the widgets field of the Meta class. In there you can define which widget from django.forms you want to use, then can define whatever attrs you want. Here we use 'class' and set its argument to 'form-control'. You could easily substitute as many css classes as you wanted, i.e

'name': TextInput(attrs={'class': 'form-control xs my-other-css-class'}),

I use this with bootstrap frequently and it works fine, so long as you import bootstrap somewhere along the line (either from the django-bootstrap plugin, or just through static files in your base template)

Styling Django Model forms

You can pass this to the attrs of the widget:

class SomeModelForm(forms.ModelForm):
class Meta:
model = SomeModel
widgets = {
'field_name': forms.TextInput(attrs={'class': 'myclass'})
}

or you can do this in the __init__ method of the ModelForm:

class SomeModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['field_name'].widget.attrs.update(class='myclass')
class Meta:
model = SomeModel


Related Topics



Leave a reply



Submit