Using Custom Widgets In Django

Using Custom Widgets In Django

In Django we use built-in forms. After rendering the template with form and form fields we can see the equivalent html is generated from the form fields. How Django is doing that ? Well, to generate HTML from the form fields django uses form Widgets. In some cases we need the some specific HTML format from Django widgets. In such cases we write our own Django form widgets.

How to write custom Django Widget ?

To write custom Django widget we use forms.Widget class Which is base class for all django Widgets. If we use bootstrap framework in our project then we may need to add some bootstrap classes to HTML form fields and we should follow some HTML structure in order to generate desired design. While writing custom widgets we override html_template and render method of the inherited forms.Widget class.

Let's see a custom django Bootstrap Widget Example

Django Custom Widget

from django import forms
from django.template import loader
from django.utils.safestring import mark_safe

class BootstrapInputWidget(forms.Widget):
    template_name = 'template.html'

    def get_context(self, name, value, attrs=None):
        return {'widget': {
            'name': name,
            'value': value,
        }}

    def render(self, name, value, attrs=None):
        context = self.get_context(name, value, attrs)
        template = loader.get_template(self.template_name).render(context)
        return mark_safe(template)

template.html

<div class="form-group input-group">
    <span class="input-group-addon">Name</span>
    <input type="text" class="form-control" id="id-{{ widget.name }}" name="{{ widget.name }}" />
</div>

forms.py

from django import forms
from django.contrib.auth.models import User
form .widgets import BootstrapInputWidget

class CreateMyModelForm(forms.ModelForm):
    first_name = forms.CharField(widget=BootstrapInputWidget())
    class Meta:
        model = User
        fields = ['name']
        widgets={'last_name':BootstrapInputWidget()}