覆盖表单的干净方法来自定义错误消息

问题描述:

我无法覆盖内置Django表单(django.contrib.auth.SetPasswordForm)的干净方法。该表单有两个字段:new_password1和new_password2。覆盖表单的干净方法来自定义错误消息

所以在我的views.py我所说的自定义表单(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')) 

在我forms.py:我想定义自己的清洁方法来显示我的自定义错误消息。这里就是我写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 

的问题是,当用户输入重复密码错误,而不是让"Missmatch" error,它给"enter pass2"!另外print password2不会打印用户输入的password2密码。

我在这段代码中做错了什么?什么是自定义错误消息的最佳方式?

p.s.在视图中使用原始SetPasswordForm工作正常。

SetPasswordForm检查new_password1new_password2匹配在clean_new_password2方法。

当密码不匹配时,new_password2不包含在self.cleaned_data中,因此您无法在clean方法中访问它。

如果您想覆盖密码不匹配的错误消息,则将其设置为error_messages字典是正确的方法。然后,我会从您的表单中删除clean方法。

如果您需要为每个字段输入不同的required错误消息,您可以在__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

感谢您的回答,那么如何设置'error_messages'字典呢? –

+0

您已经在您的问题中设置了'error_messages'字典。我已经添加了一个例子。 – Alasdair

+0

真棒tnx。猜猜我仍然是一个newby使用形式:) 我还需要在我的领域最小长度验证,我可以做这个验证使用error_messages(如果是如何?)或我必须使用干净的方法吗? –

当你调用形式超级方法def clean_new_password2(self)一切准备就绪的清洁方法被调用,所以self.cleaned_data['new_password2']是空的您需要重写clean_new_password2在你的形式,寻找源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

感谢您的回答,我如何重写'clean_new_password2'并进行其他验证? –

+0

我刚刚添加了原来的代码,将其替换为您的 –

+0

其他字段验证呢?我需要另一种干净的方法吗? –