Validation des champs avec ModelForm

Le problème exposé dans ce sujet a été résolu.

Bonjour,

J’utilise les ModelForm afin de générer des formulaires à partir de ma BDD.

Faut-il que la validation se fasse côté BDD (avec, par exemple, RegexValidator, MinLengthValidator ou bien des validateurs custom), auquel cas je modifie, côté formulaire, les messages d’erreur avec error_messages par exemple ?

Ou alors, faut-il que la validation se fasse côté formulaire (en surchargeant clean_nom_du_champs() et clean()) ?

Vous trouverez ci-dessous deux exemples (très) basiques afin d’illustrer ma question.

Méthode n°1

# models.py

from django.db import models
from django.core.validators import RegexValidator

class Table(models.Model):
    foo = models.CharField(max_length=50, validators=[RegexValidator(r'^[A-Za-z]+$')])

# forms.py

from django import forms
from .models import Table

class TableForm(forms.ModelForm):
    class Meta:
        model = Table
        fields = ['foo',]
        labels = {
            'foo': 'Entrez la valeur de foo',
        }
        error_messages = {
            'required': 'mais où est foo ?',
            'max_length': 'foo ne peut pas avoir plus de 50 caratères !',
            'invalid': 'foo ne peut contenir que des lettres !',
        }

Méthode n°2

# models.py

from django.db import models

class Table(models.Model):
    foo = models.CharField(max_length=50)

# forms.py

import re
from django import forms
from django.core.exceptions import ValidationError
from .models import Table


class TableForm(forms.ModelForm):
    class Meta:
        model = Table
        fields = ['foo',]
        labels = {
            'foo': 'Entrez la valeur de foo',
        }
    
    def clean_foo(self):
        data = self.cleaned_data['foo']
        error_messages = {}

        if not foo: error_messages['required'] = 'mais où est foo ?'
        if len(foo) > 50: error_messages['max_length'] = 'foo ne peut pas avoir plus de 50 caratères !'
        if re.match(r'^[A-Za-z]+$', data): error_messages['invalid'] = 'foo ne peut contenir que des lettres !'
        
        raise ValidationError([
             ValidationError(_(error_messages['required']), code='required'),
             ValidationError(_(error_messages['max_length']), code='max_length'),
             ValidationError(_(error_messages['invalid']), code='invalid'),
        ])

       return data

Merci pour votre aide précieuse !

Salut,

L’idée des ModelForms est vraiment d’éviter au maximum de répeter l’information qui peut être définie par le Model pour réaliser des formulaires le plus simplement possible et sans duplication d’information.

Dans le cas général, je pense que la méthode 1 est la meilleure. On garde un formulaire simple et on met le maximum d’information sur les contraintes des champs à la source même. L’exemple que tu montres semble correspondre à ce cas-là.

Ceci dit, on peut toujours inventer des cas tordus où la méthode 2 serait meilleure. Par exemple, un cas où ce qui est saisit dans un formulaire aurait des restrictions spécifiques à ce que pourrait contenir le champ en général.

Salut,

L’idée des ModelForms est vraiment d’éviter au maximum de répeter l’information qui peut être définie par le Model pour réaliser des formulaires le plus simplement possible et sans duplication d’information.

Dans le cas général, je pense que la méthode 1 est la meilleure. On garde un formulaire simple et on met le maximum d’information sur les contraintes des champs à la source même. L’exemple que tu montres semble correspondre à ce cas-là.

Ceci dit, on peut toujours inventer des cas tordus où la méthode 2 serait meilleure. Par exemple, un cas où ce qui est saisit dans un formulaire aurait des restrictions spécifiques à ce que pourrait contenir le champ en général.

Aabu

Merci pour ta réponse ! La première méthode également me semblait également être la plus propre !

Sinon il est toujours possible, j’imagine, de mélanger les deux méthodes.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte