00
:
00
:
00
:
00
•Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

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.