Validazione dei Form
La validazione dei dati e un aspetto cruciale di qualsiasi applicazione web. Django offre un sistema di validazione potente e flessibile che opera a piu livelli, dai singoli campi allâintero form.
Validazione dei Singoli Campi
Puoi validare un campo specifico definendo un metodo clean_<nomecampo>() nel form:
from django import forms
from django.core.exceptions import ValidationError
class RegistrazioneForm(forms.Form):
username = forms.CharField(max_length=50)
email = forms.EmailField()
eta = forms.IntegerField()
def clean_username(self):
username = self.cleaned_data['username']
if len(username) < 3:
raise ValidationError("Lo username deve avere almeno 3 caratteri.")
if ' ' in username:
raise ValidationError("Lo username non puo contenere spazi.")
return username
def clean_eta(self):
eta = self.cleaned_data['eta']
if eta < 18:
raise ValidationError("Devi avere almeno 18 anni per registrarti.")
return eta
Ogni metodo clean_<campo>() deve restituire il valore validato oppure sollevare un ValidationError.
Validazione dellâIntero Form
Il metodo clean() permette di validare piu campi contemporaneamente e controllare relazioni tra di essi:
class CambioPasswordForm(forms.Form):
password = forms.CharField(widget=forms.PasswordInput)
conferma_password = forms.CharField(widget=forms.PasswordInput)
def clean(self):
cleaned_data = super().clean()
password = cleaned_data.get('password')
conferma = cleaned_data.get('conferma_password')
if password and conferma and password != conferma:
raise ValidationError("Le due password non coincidono.")
return cleaned_data
ValidationError con Codici e Parametri
Puoi fornire dettagli aggiuntivi agli errori di validazione:
def clean_email(self):
email = self.cleaned_data['email']
if not email.endswith('@azienda.it'):
raise ValidationError(
"L'email %(email)s non e valida. Usa un indirizzo @azienda.it.",
code='email_non_valida',
params={'email': email},
)
return email
Validatori Riutilizzabili
I validatori sono funzioni o classi che possono essere riutilizzate su piu campi:
from django.core.validators import (
RegexValidator,
MinValueValidator,
MaxValueValidator,
MinLengthValidator,
MaxLengthValidator,
)
class ProdottoForm(forms.Form):
codice = forms.CharField(validators=[
RegexValidator(
regex=r'^[A-Z]{3}-\d{4}$',
message="Il codice deve avere il formato AAA-0000."
),
])
prezzo = forms.DecimalField(validators=[
MinValueValidator(0.01, message="Il prezzo deve essere positivo."),
MaxValueValidator(99999.99, message="Il prezzo massimo e 99999.99."),
])
descrizione = forms.CharField(validators=[
MinLengthValidator(10, message="La descrizione deve avere almeno 10 caratteri."),
])
Validatori Personalizzati come Funzioni
Puoi creare validatori personalizzati come semplici funzioni:
from django.core.exceptions import ValidationError
def valida_codice_fiscale(valore):
if len(valore) != 16:
raise ValidationError(
"Il codice fiscale deve avere esattamente 16 caratteri."
)
if not valore.isalnum():
raise ValidationError(
"Il codice fiscale puo contenere solo lettere e numeri."
)
class DatiPersonaliForm(forms.Form):
nome = forms.CharField(max_length=100)
codice_fiscale = forms.CharField(
max_length=16,
validators=[valida_codice_fiscale]
)
Validatori nei Modelli
I validatori possono essere applicati anche direttamente ai campi dei modelli:
from django.db import models
from django.core.validators import MinValueValidator, RegexValidator
class Prodotto(models.Model):
nome = models.CharField(max_length=200)
prezzo = models.DecimalField(
max_digits=10,
decimal_places=2,
validators=[MinValueValidator(0.01)]
)
codice_sku = models.CharField(
max_length=10,
validators=[RegexValidator(r'^SKU-\d+$')]
)
Errori Non Legati a Campi Specifici
Puoi aggiungere errori che non sono legati a un campo specifico nel metodo clean():
class PrenotazioneForm(forms.Form):
data_inizio = forms.DateField()
data_fine = forms.DateField()
def clean(self):
cleaned_data = super().clean()
inizio = cleaned_data.get('data_inizio')
fine = cleaned_data.get('data_fine')
if inizio and fine:
if fine <= inizio:
self.add_error('data_fine', "La data di fine deve essere successiva.")
if (fine - inizio).days > 30:
self.add_error(None, "La prenotazione non puo superare i 30 giorni.")
return cleaned_data
Il metodo add_error(None, ...) aggiunge un errore globale (non-field error).
Conclusione
La validazione dei form in Django opera su piu livelli: dai validatori sui singoli campi, ai metodi clean_<campo>() per logiche specifiche, fino al metodo clean() per validazioni che coinvolgono piu campi. Questo approccio stratificato garantisce dati sempre corretti e messaggi di errore chiari per gli utenti.