Forms
Backend half of forms (there is also frontend part)
Definition: Django Form:
A Python class that defines field behavior and validation rules for user inputs.
Properties: Forms backend pieces
forms.py: The standard location for form classes within a Django app.forms.ModelForm: Specialized form that maps directly to a Django Model.forms.Form: Standard form for inputs not tied to a database table.
Workflow: Adding a forms.ModelForm
Identify the Model requiring user input.
Open
forms.pyand import dependencies:from django import forms from .models import Book
Create the class with a
Metainner class:class BookForm(forms.ModelForm): class Meta: model = Book fields = ['title', 'author']
Define
widgetsfor field-specific attributes (placeholders, rows, or AlpineJS attrs):widgets = { 'text': forms.Textarea(attrs={ 'rows': 4, 'placeholder': 'Enter book description...' }), 'published_date': forms.TextInput(attrs={ 'x-mask': '99/99/9999', 'placeholder': 'MM/DD/YYYY' }), }
Use the form in
views.py:@require_POST def update_book(request, pk): book = Book.objects.get(pk=pk) form = BookForm(request.POST or None, instance=book) if form.is_valid(): form.save()
Properties: Fields
forms.CharField - A field for string input:
title = forms.CharField( max_length=200, widget=forms.Textarea(attrs={'rows': 4, 'cols': 40}), label="Book Title" )
forms.DateTimeField - A field for date and time input:
published_at = forms.DateTimeField( widget=forms.DateTimeInput(attrs={'type': 'datetime-local'}), initial=timezone.now, label="Publication Date" )
forms.ModelChoiceField - A ChoiceField whose choices are a model QuerySet:
author = forms.ModelChoiceField( queryset=Author.objects.all().order_by('name'), empty_label="Select an Author...", label="Author" )
forms.ModelMultipleChoiceField - Allows selecting multiple instances:
genres = forms.ModelMultipleChoiceField( queryset=Genre.objects.all(), widget=forms.CheckboxSelectMultiple, label="Genres" )
Workflow: Cleaning the data
Add method for field you want to clean
def clean_field_name(self): self.field_name = self.field_name.upper()
Call
full_clean()before saving the model