2017-08-02 2 views
1

Je rencontre des problèmes pour remplacer la méthode propre d'un formulaire Django intégré (django.contrib.auth.SetPasswordForm). Ce formulaire a deux champs: new_password1 et new_password2.redéfinir la méthode propre du formulaire pour personnaliser les messages d'erreur

donc dans mon views.py j'appelle le formulaire personnalisé (MySetPasswordForm):

def reset_confirm(request, uidb64=None, token=None): 
    return password_reset_confirm_delegate(request, 
     template_name='app/reset_confirm.html', 
     set_password_form = MySetPasswordForm, uidb64=uidb64, 
     token=token, post_reset_redirect=reverse('main_page')) 

Dans mon forms.py: Je veux définir ma propre méthode propre pour montrer mes messages d'erreur personnalisés. voici comment je l'ai écrit MySetPasswordForm:

from django.contrib.auth.forms import SetPasswordForm 
class MySetPasswordForm(SetPasswordForm): 
    error_messages = { 'password_mismatch': _("Missmatch!"), } 

    def clean(self): 
     password1 = self.cleaned_data.get('new_password1', '') 
     password2 = self.cleaned_data.get('new_password2', '') 

     print password1 #prints user's entered value 
     print password2 #prints nothing!! 
     print self.data['new_password2'] #prints user's entered value 

     if password1 == '': 
      self._errors["new_password1"] = ErrorList([u"enter pass1!"]) 

     if password2 == '': 
      self._errors["new_password2"] = ErrorList([u"enter pass2"]) 

     elif password1 != password2: 
      raise forms.ValidationError(
        self.error_messages['password_mismatch'], 
        code='password_mismatch', 
       ) 
     return self.cleaned_data 

Le problème est que lorsque l'utilisateur d'entrer le mot de passe de répétition mal, au lieu d'obtenir "Missmatch" error, il donne "enter pass2"! De même, print password2 n'imprime pas la valeur saisie par l'utilisateur pour le mot de passe2. Qu'est-ce que je fais de mal dans ce code ?! et quelle est la meilleure façon de faire des messages d'erreur personnalisés?

p.s. L'utilisation de SetPasswordForm d'origine dans la vue fonctionne correctement.

Répondre

2

Le SetPasswordForm vérifie que new_password1 et new_password2 correspondent dans la méthode clean_new_password2.

Lorsque les mots de passe ne correspondent pas, new_password2 n'est pas inclus dans self.cleaned_data, donc vous ne pouvez pas y accéder dans la méthode clean.

Si vous souhaitez remplacer le message d'erreur pour les mots de passe incompatibles, définissez-le dans le dict error_messages est l'approche correcte. Je voudrais ensuite supprimer la méthode clean de votre formulaire.

Si vous avez besoin d'un message d'erreur required différent pour chaque champ, vous pouvez le définir dans la méthode __init__.

class MySetPasswordForm(SetPasswordForm): 
    error_messages = { 
     'password_mismatch': _("Missmatch!"), 
     'required': _("Please enter a password"), # If you do not require the fieldname in the error message 
    } 

    def __init__(self, *args, **kwargs): 
     super(MySetPasswordForm, self).__init__(*args, **kwargs) 
     self.fields['new_password1'].error_messages['required'] = _("enter pass1!") 
+0

Merci pour la réponse , alors comment puis-je définir le dict 'error_messages'? –

+0

Vous définissez déjà le dict 'error_messages' dans votre question. J'ai ajouté un exemple. – Alasdair

+0

impressionnant tnx. Je suppose que je suis encore un débutant dans l'utilisation des formulaires :) J'ai aussi besoin d'une validation min-length sur mon terrain, puis-je faire cette validation en utilisant error_messages (si oui comment?) Ou dois-je utiliser la méthode clean? –

1

Lorsque vous appelez la méthode propre de la forme super méthode def clean_new_password2(self) tout prêt est appelé, donc self.cleaned_data['new_password2'] est vide, vous devez remplacer le clean_new_password2 dans votre formulaire, chercher la source auth forms

class MySetPasswordForm(SetPasswordForm): 

    def clean_new_password2(self): 
     password1 = self.cleaned_data.get('new_password1') 
     password2 = self.cleaned_data.get('new_password2') 
     if password1 and password2: 
      if password1 != password2: 
       raise forms.ValidationError(
        self.error_messages['password_mismatch'], 
        code='password_mismatch', 
       ) 
     return password2 
+0

Merci pour la réponse, comment puis-je remplacer clean_new_password2 et faire d'autres validations? –

+0

Je viens d'ajouter le code original le remplacer par le vôtre –

+0

qu'en est-il des autres validations de champ? Ai-je besoin d'une autre méthode propre pour eux? –