J'ai un formulaire qui ne doit être validé qu'après avoir été nettoyé.
Que se passe-t-il lorsque vous exécutez form.is_valid()
? Le formulaire est-il nettoyé, puis cette version nettoyée du formulaire est-elle validée?
Le comportement que j'obtiens en ce moment, c'est que si mon champ ne passe pas la validation avant le nettoyage, même si le nettoyage le ferait passer, is_valid()
retourne False
.
Est-ce que je fais quelque chose de mal?
# View
class ContactForm(forms.Form):
message = forms.CharField(widget=forms.Textarea, max_length=5)
def clean_message(self):
message = self.cleaned_data['message']
return message.replace('a', '') # remove all "a"s from message
def contact(request):
if request.method == 'POST':
if form.is_valid():
return HttpResponseRedirect('/contact/on_success/')
else:
return HttpResponseRedirect('/contact/on_failure/')
Je veux que form.is_valid()
renvoie True
si le message contient moins de 5 caractères PAS y compris a
!
Est-il possible d'exécuter clean_<fieldname>()
après to_python()
mais avant run_validators()
? Ou devrais-je faire cela d'une autre manière?
Je pense que le processus de validation du formulaire (et son ordre correct) est vraiment bien documenté. http://docs.djangoproject.com/en/dev/ref/forms/validation/#form-and-field-validation
Pourriez-vous partager votre code? Il existe une méthode clean
sur chaque champ de formulaire, responsable de l'exécution de to_python
, validate
et run_validators
(dans cet ordre). to_python
accepte la valeur brute du widget, en la forçant dans un python, validate
prend la valeur contrainte et exécute une validation spécifique au champ.
Réponse mise à jour par rapport au code donné
clean_message
est appelé après que toutes les autres validations se soient déroulées comme to_python
, validate
et, surtout, run_validators
. Je pense que la dernière méthode vérifiera que le max_length
la contrainte n'est pas violée. Donc, vous modifiez les données par la suite n'a aucun effet.
La solution est d'élever un ValidationError
ici. Suppression de max_length
évitera toute validation de la longueur de l'entrée.
class ContactForm(forms.Form):
message = forms.CharField(widget=forms.Textarea)
def clean_message(self):
message = self.cleaned_data['message']
message = message.replace('a', '') # remove all "a"s from message
if len(message) >= 5:
raise ValidationError('Too many characters ...')
return message
De plus, lorsque is_valid()
retourne False
, vous pouvez vérifier pourquoi, en imprimant self.errors
À l'intérieur du formulaire.
si vous regardez le code is_valid()
, cela vérifie le formulaire is_bound
et le self.errors
est vide
Vous pouvez remplacer CharField:
class CustomCharField(forms.CharField):
def clean(self, value):
return super().clean(value.replace('a', ''))
Ensuite, vous pouvez l'utiliser sous forme
class ContactForm(forms.Form):
message = CustomCharField(widget=forms.Textarea)