What are Django Forms?

Django forms handle HTML form creation, validation, and processing. They provide a convenient way to work with form data and reduce boilerplate code.

Creating a Form

Define forms in forms.py:

from django import forms

class ContactForm(forms.Form):
    name = forms.CharField(max_length=100)
    email = forms.EmailField()
    message = forms.CharField(widget=forms.Textarea)
    age = forms.IntegerField(min_value=0, max_value=120)

Form Fields

Common form field types:

class MyForm(forms.Form):
    # Text fields
    name = forms.CharField(max_length=100)
    description = forms.CharField(widget=forms.Textarea)
    
    # Numbers
    age = forms.IntegerField()
    price = forms.DecimalField(max_digits=10, decimal_places=2)
    
    # Choices
    country = forms.ChoiceField(choices=[('US', 'USA'), ('UK', 'UK')])
    language = forms.MultipleChoiceField(choices=[...])
    
    # Boolean
    agree = forms.BooleanField()
    
    # Date/Time
    birth_date = forms.DateField()
    created_at = forms.DateTimeField()
    
    # File upload
    photo = forms.ImageField()
    document = forms.FileField()

Using Forms in Views

Handle form submission:

from django.shortcuts import render, redirect
from .forms import ContactForm

def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            # Process valid data
            name = form.cleaned_data['name']
            email = form.cleaned_data['email']
            # Save or send email
            return redirect('success')
    else:
        form = ContactForm()
    
    return render(request, 'contact.html', {'form': form})

Rendering Forms in Templates

Display forms in templates:

<!-- Render entire form -->
{{ form.as_p }}

<!-- Render as table -->
{{ form.as_table }}

<!-- Render as list -->
{{ form.as_ul }}

<!-- Manual rendering -->
<form method="post">
    {% csrf_token %}
    {{ form.name.label_tag }}
    {{ form.name }}
    {{ form.name.errors }}
    
    {{ form.email.label_tag }}
    {{ form.email }}
    {{ form.email.errors }}
    
    <button type="submit">Submit</button>
</form>

Form Validation

Custom validation:

class ContactForm(forms.Form):
    email = forms.EmailField()
    confirm_email = forms.EmailField()
    
    def clean(self):
        cleaned_data = super().clean()
        email = cleaned_data.get('email')
        confirm_email = cleaned_data.get('confirm_email')
        
        if email != confirm_email:
            raise forms.ValidationError("Emails don't match")
        
        return cleaned_data

Model Forms

Create forms from models:

from django import forms
from .models import User

class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['name', 'email', 'age']
        # Or exclude: exclude = ['created_at']

Best Practices

  • Always validate: Use is_valid() before processing
  • Use cleaned_data: Access validated data
  • Handle errors: Display validation errors in templates
  • Use CSRF token: Always include in forms

Next Steps

Learn about Django Views to process forms, or explore templates for rendering.