Chapter 8: Django Forms
8.1 Form Basics
Form Class Definition
The Django form system provides a powerful and flexible way to handle HTML forms. Form classes inherit from django.forms.Form and are used to define form fields and validation logic.
Basic form class definition:
python
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
email = forms.EmailField()
subject = forms.CharField(max_length=200)
message = forms.CharField(widget=forms.Textarea)Form Field Types
Django provides multiple built-in form field types, each with specific validation rules:
python
from django import forms
from django.core.validators import RegexValidator
class ExampleForm(forms.Form):
# String field
name = forms.CharField(
max_length=100,
min_length=2,
label='Name',
help_text='Please enter your real name'
)
# Email field
email = forms.EmailField(
label='Email Address',
help_text='Please enter a valid email address'
)
# Integer field
age = forms.IntegerField(
min_value=0,
max_value=150,
label='Age'
)
# Float field
salary = forms.FloatField(
min_value=0,
label='Salary'
)
# URL field
website = forms.URLField(
required=False,
label='Personal Website'
)
# Date field
birth_date = forms.DateField(
label='Birth Date',
widget=forms.DateInput(attrs={'type': 'date'})
)
# DateTime field
appointment = forms.DateTimeField(
label='Appointment Time'
)
# Boolean field
subscribe = forms.BooleanField(
required=False,
label='Subscribe to Email'
)
# Choice field
GENDER_CHOICES = [
('male', 'Male'),
('female', 'Female'),
('other', 'Other')
]
gender = forms.ChoiceField(
choices=GENDER_CHOICES,
label='Gender'
)
# Multiple choice field
INTERESTS_CHOICES = [
('tech', 'Technology'),
('sports', 'Sports'),
('music', 'Music'),
('travel', 'Travel')
]
interests = forms.MultipleChoiceField(
choices=INTERESTS_CHOICES,
widget=forms.CheckboxSelectMultiple,
label='Interests'
)
# File field
avatar = forms.ImageField(
required=False,
label='Avatar'
)
# Custom validation field
phone = forms.CharField(
validators=[RegexValidator(
regex=r'^\+?1?\d{9,15}$',
message="Please enter a valid phone number"
)],
label='Phone Number'
)Form Validation
Django forms provide multiple validation mechanisms:
- Field-level validation
- Form-level validation
- Custom validation methods
python
from django import forms
from django.core.exceptions import ValidationError
class RegistrationForm(forms.Form):
username = forms.CharField(max_length=150)
email = forms.EmailField()
password = forms.CharField(widget=forms.PasswordInput)
password_confirm = forms.CharField(widget=forms.PasswordInput)
def clean_username(self):
"""Validate if username already exists"""
username = self.cleaned_data['username']
if User.objects.filter(username=username).exists():
raise ValidationError("Username already exists")
return username
def clean_email(self):
"""Validate if email already exists"""
email = self.cleaned_data['email']
if User.objects.filter(email=email).exists():
raise ValidationError("Email already registered")
return email
def clean(self):
"""Form-wide validation"""
cleaned_data = super().clean()
password = cleaned_data.get('password')
password_confirm = cleaned_data.get('password_confirm')
if password and password_confirm and password != password_confirm:
raise ValidationError("Passwords do not match")
return cleaned_dataForm Rendering
Django provides multiple ways to render forms:
html
<!-- forms.py -->
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
email = forms.EmailField()
subject = forms.CharField(max_length=200)
message = forms.CharField(widget=forms.Textarea)
<!-- views.py -->
from django.shortcuts import render
from .forms import ContactForm
def contact_view(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
# Process form data
name = form.cleaned_data['name']
email = form.cleaned_data['email']
# Send email and other operations
return render(request, 'contact_success.html')
else:
form = ContactForm()
return render(request, 'contact.html', {'form': form})
<!-- contact.html -->
<form method="post">
{% csrf_token %}
<!-- Method 1: Manually render each field -->
<div>
<label for="{{ form.name.id_for_label }}">Name:</label>
{{ form.name }}
{% if form.name.errors %}
<div class="error">{{ form.name.errors }}</div>
{% endif %}
</div>
<!-- Method 2: Use form's as_p method -->
{{ form.as_p }}
<!-- Method 3: Use form's as_table method -->
<table>
{{ form.as_table }}
</table>
<!-- Method 4: Use form's as_ul method -->
<ul>
{{ form.as_ul }}
</ul>
<button type="submit">Submit</button>
</form>
<!-- Method 5: Loop through fields -->
<form method="post">
{% csrf_token %}
{% for field in form %}
<div class="form-group">
{{ field.label_tag }}
{{ field }}
{% if field.errors %}
<div class="error">
{% for error in field.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
{% if field.help_text %}
<small class="help-text">{{ field.help_text }}</small>
{% endif %}
</div>
{% endfor %}
<button type="submit">Submit</button>
</form>Using CSS classes and attributes in templates:
python
# forms.py
class StyledForm(forms.Form):
name = forms.CharField(
widget=forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Please enter your name'
})
)
email = forms.EmailField(
widget=forms.EmailInput(attrs={
'class': 'form-control',
'placeholder': 'Please enter your email'
})
)Through this approach, you can create a complete form system with full functionality and validation.
Summary
Django form basics are the core of web application interaction:
- ✅ Form classes define form structure and validation rules
- ✅ Multiple field types meet different data requirements
- ✅ Multi-level validation mechanisms ensure data validity
- ✅ Flexible form rendering methods
- ✅ Good integration with CSS frameworks like Bootstrap
Mastering form basics is the prerequisite for building user interaction features.
Next
We will learn about using ModelForm.