Introduction
Handling user input is a key part of any web application.
In Django, forms provide a clean and powerful way to:
- Collect user input
- Validate data
- Save it to the database
Whether you’re building a contact form, registration page, or complex multi-step forms, Django forms make it fast, secure, and maintainable.
In this article, we’ll cover:
- Django form basics
- Model forms
- Validation and custom validation
- Best practices
Django Forms Basics
A form is a Python class that defines the fields you want the user to fill.
Example: Simple contact form
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea)
Using the Form in a View
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']
message = form.cleaned_data['message']
# Here, you could send an email or save to DB
else:
form = ContactForm()
return render(request, 'contact.html', {'form': form})
Rendering Forms in Templates
Django templates make it easy:
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Send</button>
</form>
{{ form.as_p }}→ Renders each field in a<p>tag- CSRF token ensures security
You can also use {{ form.as_table }} or {{ form.as_ul }}.
Model Forms: Connecting Forms to Models
Model forms automatically generate form fields from Django models.
Example:
from django.forms import ModelForm
from .models import BlogPost
class BlogPostForm(ModelForm):
class Meta:
model = BlogPost
fields = ['title', 'content', 'author']
Using ModelForm in Views
def create_post(request):
if request.method == 'POST':
form = BlogPostForm(request.POST)
if form.is_valid():
form.save()
else:
form = BlogPostForm()
return render(request, 'blog/create_post.html', {'form': form})
Model forms save time and reduce boilerplate.
Form Validation
Django provides built-in validation and allows custom validation.
Example: Built-in validation
email = forms.EmailField() # Ensures a valid email
Custom validation
class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea)
def clean_name(self):
data = self.cleaned_data['name']
if "spam" in data.lower():
raise forms.ValidationError("Invalid name")
return data
clean_<fieldname>→ Validates individual fieldsclean()→ Validates multiple fields together
Advanced Tips
1. Custom Widgets
Customize how fields are displayed:
message = forms.CharField(widget=forms.Textarea(attrs={'rows': 5, 'cols': 50}))
2. Formsets
Handle multiple copies of the same form:
from django.forms import formset_factory
ContactFormSet = formset_factory(ContactForm, extra=3)
3. Error Handling
Display errors clearly:
{% for field in form %}
{{ field.label_tag }}
{{ field }}
{% for error in field.errors %}
<p class="error">{{ error }}</p>
{% endfor %}
{% endfor %}
Best Practices
✔ Keep logic in views, not templates
✔ Use ModelForms whenever possible
✔ Always use CSRF protection
✔ Validate data carefully, especially for user input
✔ Organize forms by app in forms.py
Final Thoughts
Django forms are more than just HTML inputs. They provide:
- Data validation
- Security
- Connection to database models
Mastering Django forms allows you to handle user input safely and efficiently, whether it’s a simple contact form or a complex multi-step form.