How to Style Your Django Forms

Spoiler: You have to use widgets.

Gustavo Maciel
The Startup
4 min readJan 13, 2021

--

Photo by Joshua Aragon on Unsplash

Everyone who uses Django knows how good the Django forms can be. But when you are using it for the first time, a question araises: How can I style it? How can I add a class?

Well, there’s a way (quite simple actually), you have to use widgets.

But what is that exactly? Let’s see the definition of widget, according to Django Docs:

A widget is Django’s representation of an HTML input element. The widget handles the rendering of the HTML, and the extraction of data from a GET/POST dictionary that corresponds to the widget.

In other words, widget is just a way to define how that content will be rendered as HTML. So, for example, a CharField has a default widget of TextInput that renders as <input type="text"> .

But widgets are customizable, so you can also set things like the size of that textarea or if that field is going to be a required field and so goes on…

So, let’s try to build a example to show the widgets in action.

Suppose we have a form called UserInfoForm to get the name of the user and also his email.

And the HTML looks like this:

Right now this form is using the default widgets, and it doesn’t have any style, so, basically, it looks like this:

So, to change it, we need to customize the appearance. You can customize widgets in two ways — it can be via widget instance or widget class. For this first example, I’ll be using widget instance. Basically you have to use the Widget.attrs argument, which is a dictionary containing HTML attributes to be set to the rendered widget, like the example below:

And then we can see the attrs dictionary taking placeholder as a key an the Name as value as long with the style as key and the width: 300px; as value.

And this is the result:

Much better, right? But it still can be improved, we can add a Bootstrap class to it. And we can do this by declaring a class inside the attrs dictionary.

We’ve added a Bootstrap class and this is the result.

Now it’s good!

But usually when we are using Django forms, those forms are related to some model — and right now, this form isn’t. To that happen, we need to make a few more changes. We’re going to use the widget class now. The widget class has a basic attribute attrs, just like the the example above. We also have to add a new class called Meta and specify the name of the model this form is related to, the fields we want to have and finally the widgets for those fields.

So, what’s going on here? The CharField and the EmailField that we were using before are Built-in Field classes, but if we are going to work with widgets class, we need to use the Built-in widgets (and these widgets are TextInput and EmailInput, for this example). They will work the same in the end but the configuration will be slightly different.

This is basically the same form as before, it didn’t change the way it gets rendered or anything, but now this form is connected to the User model, which is the one that was created to store the user info.

And the HTML looks like this:

The final result:

Conclusion

Learning how to use widgets is great because now you know how to make those forms look better and how simple it is to add a Bootstrap class, which can be handy.

You can check the source code of this project on Github.

Of course there’s much more you can do with widgets. And the best place to learn is from the official documentation — aka Django docs.

--

--

Gustavo Maciel
The Startup

Focused on building reliable systems with strong performance and efficiency.