Forms and User Input
Handling user input is a common requirement in web applications. Django provides a robust and flexible framework for working with forms, including tools for form handling, validation, and integration with models.
Django Form Handling
Django forms are Python classes that represent HTML forms. They provide an easy way to handle user input, validate data, and render forms in templates.
Creating a Form
To create a form, define a class that inherits from django.forms.Form
. Each form field is defined as a class attribute.
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea)
Rendering a Form in a Template
To render a form in a template, pass an instance of the form to the template context and use the form object in the template.
Python file:
from django.shortcuts import render
from .forms import ContactForm
def contact(request):
form = ContactForm()
return render(request, 'contact.html', {'form': form})
HTML file:
<!-- contact.html -->
<form method="post" action="/contact/">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Send</button>
</form>
In this example, form.as_p
renders the form fields wrapped in <p>
tags.
Processing Form Data
When a user submits the form, we need to process the data in our view.
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import ContactForm
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
# Process the data in form.cleaned_data
name = form.cleaned_data['name']
email = form.cleaned_data['email']
message = form.cleaned_data['message']
# Redirect after processing
return HttpResponseRedirect('/thanks/')
else:
form = ContactForm()
return render(request, 'contact.html', {'form': form})
Form Validation
Django forms provide built-in validation methods to ensure that the data submitted by the user is valid.
Built-in Validators
Each form field type comes with its own built-in validators. For example, CharField
validates that the input is a string, and EmailField
validates that the input is a valid email address.
class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea)
Custom Validators
You can add custom validation logic by defining a clean_<fieldname>
method in your form class.
class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea)
def clean_name(self):
name = self.cleaned_data.get('name')
if "badword" in name:
raise forms.ValidationError("Bad word detected!")
return name
Global Form Validation
To add validation that spans multiple fields, override the clean
method of the form class.
class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea)
def clean(self):
cleaned_data = super().clean()
name = cleaned_data.get('name')
email = cleaned_data.get('email')
if name and email:
if "example" in email:
raise forms.ValidationError("Example email addresses are not allowed.")
Model Forms
Model forms are a shortcut for creating forms based on Django models. They provide a way to create forms directly from your models.
Creating a Model Form
To create a model form, define a class that inherits from django.forms.ModelForm
and specify the model and fields.
Model:
from django.db import models
class Contact(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField()
message = models.TextField()
Model Form:
from django import forms
from .models import Contact
class ContactForm(forms.ModelForm):
class Meta:
model = Contact
fields = ['name', 'email', 'message']
Using a Model Form in a View
Using a model form in a view is similar to using a regular form.
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import ContactForm
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
form.save() # Saves the form data to the database
return HttpResponseRedirect('/thanks/')
else:
form = ContactForm()
return render(request, 'contact.html', {'form': form})