DEV Community

Lody G Mtui
Lody G Mtui

Posted on

How to Customize Django Forms using Django Widget Tweaks

Django is the "battery-included" framework as most of the functionalities are already done or automated by the framework itself.
This makes it simpler for the developers to complete their work by the deadlines suggested.

Django has many options that enable the forms to render data from the model using ModelForm class.

But Django forms can be automated by using the following

  • {{form.as_p}} - render forms as paragraph

  • {{form.as_table}} - render forms as table

  • {{form.as_ul}} - render forms as list

But all these automate the Django forms implicitly. For instance, you make the Django form using Model Form and by using form.as_p....

models.py

from django.db import models

class Post(models.Model):
    firstname = models.CharField()
    lastname = models.CharField()
    email = models.EmailField()

    def __str__(self):
        return self.firstname
Enter fullscreen mode Exit fullscreen mode

forms.py

from django import forms
from .models import Post

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ['posts', 'caption']
Enter fullscreen mode Exit fullscreen mode

views.py


def getPost(request):
    post = Post.objects.all()
    context = {
        'post':post
    }
    return render(request,'post_form.html',context)
Enter fullscreen mode Exit fullscreen mode

post_form.html

<div class="col-md-4">
  <form class="form" method="post" enctype="multipart/form-data">
     {% csrf_token %}
     <fieldset class="form-group">
       <legend class="text-center mb-4">Upload Post</legend>
       {{form.as_p}}
     </fieldset>

     <button type="submit" class="btn btn-primary">Post</button>
  </form>
</div>
Enter fullscreen mode Exit fullscreen mode

Suppose you want to use your own HTML forms in stead of automating using Django itself.
E.g of HTML form

<form action="">
  <label for="fname">First name:</label><br>
  <input type="text" id="fname" value="John"><br><br>
  <label for="lname">Last name:</label><br>
  <input type="text" id="lname" value="Doe"><br><br>
  <label for="email">Email:</label><br>
  <input type="email" id="email" value="john@gmail.com"><br><br>
  <input type="submit" value="Submit">
</form>
Enter fullscreen mode Exit fullscreen mode

In order to render this form, you need to use a Django package known as Django Tweaks.

pip install django-widget-tweaks

Then, add it to the settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    #New
    'widget_tweaks'
]
Enter fullscreen mode Exit fullscreen mode

And in the templates, don't forget to load it as follows:-
{% load widget_tweaks %}

The Django Tweaks library includes two options to customize forms i.e.

Use render_field

<form>
   <div class="form-group">
     {% render_field form.firstname class="form-control" 
     placeholder=form.firstname.label type="text" %}
   </div>

   <div class="form-group">
     {% render_field form.lastname class="form-control" 
     placeholder=form.lastname.label type="text" %}
   </div>

   <div class="form-group">
     {% render_field form.email class="form-control" 
     placeholder=form.email.label type="email" %}
   </div>
</form>
Enter fullscreen mode Exit fullscreen mode

Using template filters

In the post_form.html file above, replace form.as_p with the following :-

{% for hidden in form.hidden_fields %}
  {{ hidden }}
{% endfor %}

{% for field in form.visible_fields %}
  <div class="form-group">
    <label for="{{ field.id_for_label }}">{{ field.label }}</label>
    {{ field|add_class:'form-control' }}    
    {% for error in field.errors %}
      <span class="help-block">{{ error }}</span>
    {% endfor %}
  </div>
{% endfor %}
Enter fullscreen mode Exit fullscreen mode

Django tweaks library is essential tool to use to customize HTML forms and it is flexible to any form of your choice.

References

Top comments (0)