Detailed Explanation of Widgets Use of django Form

  • 2021-07-24 11:22:21
  • OfStack

Preface

Don't confuse Widget with the fields field of the form. Form fields are responsible for validating the input and using it directly in the template. Widget is responsible for rendering the input elements of the HTML form on the Web page and extracting the submitted raw data. widget is an intrinsic attribute of a field, which defines what HTML element the field is presented in the browser page.

1. Specify the widget to use

Each field has a default widget type. If you want to use a different Widget, you can use the widget parameter when defining the field. Like this:


from django import forms

class CommentForm(forms.Form):
  name = forms.CharField()
  url = forms.URLField()
  comment = forms.CharField(widget=forms.Textarea)

This will use an Textarea Widget to present the comment field of the form instead of the default TextInput Widget.

2. Set the parameters of widget

Many widget have optional additional parameters. In the following example, the years property of SelectDateWidget is set, paying attention to how the parameters are passed:


from django import forms

BIRTH_YEAR_CHOICES = ('1980', '1981', '1982')
FAVORITE_COLORS_CHOICES = (
  ('blue', 'Blue'),
  ('green', 'Green'),
  ('black', 'Black'),
)

class SimpleForm(forms.Form):
  birth_year = forms.DateField(widget=forms.SelectDateWidget(years=BIRTH_YEAR_CHOICES))
  favorite_colors = forms.MultipleChoiceField(
    required=False,
    widget=forms.CheckboxSelectMultiple,
    choices=FAVORITE_COLORS_CHOICES,
  )

3. Add CSS style to widget

By default, when Django renders Widget to the actual HTML code, it will not add any CSS style to you, which means that all TextInput elements on the web page will look the same.

Look at the form below:


from django import forms

class CommentForm(forms.Form):
  name = forms.CharField()
  url = forms.URLField()
  comment = forms.CharField()

This form contains three default TextInput Widget, rendered the default way, with no CSS classes and no additional properties. The input box of each Widget will be rendered as 1-mode 1, ugly and monotonous:


>>> f = CommentForm(auto_id=False)
>>> f.as_table()
<tr><th>Name:</th><td><input type="text" name="name" required /></td></tr>
<tr><th>Url:</th><td><input type="url" name="url" required /></td></tr>
<tr><th>Comment:</th><td><input type="text" name="comment" required /></td></tr>

In a real web page, you don't want every Widget to look the same. You may want to give comment1 a larger input box, or you may want 'name' Widget to have one special CSS class.

You can do this by using the Widget. attrs parameter when creating Widget:


class CommentForm(forms.Form):
  name = forms.CharField(widget=forms.TextInput(attrs={'class': 'special'}))
  url = forms.URLField()
  comment = forms.CharField(widget=forms.TextInput(attrs={'size': '40'}))

Pay attention to the way parameters are passed!

The result after this rendering is different:


>>> f = CommentForm(auto_id=False)
>>> f.as_table()
<tr><th>Name:</th><td><input type="text" name="name" class="special" required /></td></tr>
<tr><th>Url:</th><td><input type="url" name="url" required /></td></tr>
<tr><th>Comment:</th><td><input type="text" name="comment" size="40" required /></td></tr>

Related articles: