Avec les newforms de Django, il est relativement facile d’ajouter des validations personnalisées à vos champs : il faut simplement créer une classe dérivée du type de champ que vous souhaitez utiliser.
Dans cet exemple, nous allons simplement vérifier que l’utilisateur donné n’existe pas (pour, par exemple, un formulaire d’inscription). Il faut effectuer quelques imports avant tout, bien sûr :
from django import newforms as forms from django.contrib.auth.models import User
Pour un créer champ classique, on pourrait utiliser :
nom_utilisateur = CharField(label="Nom d'utilisateur", min_length=3, max_length=128)
Nous allons donc dériver CharField :
class UserField(forms.CharField):
Comme nous l’avons vu dans le précédent article, la validation des différents champs est définie dans leurs méthodes clean. Il suffit donc de l’étendre :
def clean(self, value):
super(UserField, self).clean(value)
super permet d’appeler la méthode clean de la classe parente, qui vérifie notamment que la longueur du champ est bien comprise dans l’intervalle [min_length, max_length] et qu’il est rempli si l’attribut required est à True. C’est une ligne à placer au début de toute méthode d’une classe dérivée (évidemment, seulement si elle est étendue, c’est à dire définie dans la classe parente) pour éviter les soucis.
La vérification, enfin :
try:
User.objects.get(username=value)
raise forms.ValidationError("Quelqu'un utilise déjà ce nom d'utilisateur ! Choisissez-en un autre.")
except User.DoesNotExist:
return value
L’explication est très simple : on cherche tout d’abord un utilisateur existant déjà et avec cet identifiant. Si il n’existe pas, alors Django lève une exception User.DoesNotExist, et on peut retourner la valeur pour dire que tout va bien. Par contre, si l’utilisateur existe, la fin du try est exécutée, et une exception ValidationError est levée, avec le texte d’explication fourni en argument (qui sera affiché comme l’erreur "Ce champ est obligatoire").
La ligne du formulaire qui va créer le champ ressemble désormais à :
nom_utilisateur = UserField(label="Nom d'utilisateur", min_length=3, max_length=128)
Django va ensuite se débrouiller tout seul, empêcher de valider le formulaire, et ajouter l’erreur à form.errors. Plus besoin de faire quoi que ce soit, si vous affichez votre formulaire grâce à form dans votre gabarit (ou même si vous séparez erreurs et champs, avec form.errors ).
Simple, et efficace !