Introduction
Form fields let users enter data. Widgets show how these fields look on the page.
Jump into concepts and practice - no test required
Form fields let users enter data. Widgets show how these fields look on the page.
from django import forms class MyForm(forms.Form): name = forms.CharField(widget=forms.TextInput(attrs={'class': 'my-class'})) age = forms.IntegerField(widget=forms.NumberInput()) agree = forms.BooleanField(widget=forms.CheckboxInput())
Each form field has a type like CharField or IntegerField.
Widgets control the HTML input element shown for that field.
name = forms.CharField(widget=forms.TextInput())
email = forms.EmailField(widget=forms.EmailInput())
color = forms.CharField(widget=forms.TextInput(attrs={'type': 'color'}))subscribe = forms.BooleanField(widget=forms.CheckboxInput())
This form collects a name, email, message, and a subscription checkbox. Widgets customize placeholders and input types.
from django import forms class ContactForm(forms.Form): full_name = forms.CharField(label='Full Name', max_length=100, widget=forms.TextInput(attrs={'placeholder': 'Your full name'})) email = forms.EmailField(label='Email Address', widget=forms.EmailInput(attrs={'placeholder': 'you@example.com'})) message = forms.CharField(label='Message', widget=forms.Textarea(attrs={'rows': 4, 'cols': 40})) subscribe = forms.BooleanField(label='Subscribe to newsletter', required=False, widget=forms.CheckboxInput())
Widgets can be customized with HTML attributes using attrs.
BooleanField uses CheckboxInput by default for yes/no choices.
Always set required=False for optional fields like checkboxes.
Form fields define what data users enter.
Widgets control how the input looks and behaves.
You can customize widgets with HTML attributes for better user experience.
Form field in Django?attrs dictionary.widget=forms.TextInput(attrs={'placeholder': 'Enter name'}). Others misuse or omit attrs.email = forms.EmailField(widget=forms.EmailInput(attrs={'class': 'email-field', 'aria-label': 'Email address'}))EmailInput, which renders an input with type="email".attrs dictionary adds class="email-field" and aria-label="Email address" to the input element.age = forms.IntegerField(widget=forms.TextInput(attrs={'type': 'number'}))NumberInput.TextInput with attrs={'type': 'number'} tries to force input type but is not the recommended way and may cause issues.CharField with PasswordInput widget to hide characters.attrs dictionary passed to the widget.PasswordInput(attrs={...}). password = forms.PasswordField(widget=forms.TextInput(attrs={'placeholder': 'Enter your password', 'class': 'password-input'})) uses non-existent PasswordField. password = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Enter your password', 'class': 'password-input'})) uses TextInput which renders type="text" and does not hide characters. password = forms.CharField(widget=forms.PasswordInput(placeholder='Enter your password', class='password-input')) passes attrs incorrectly.