首页 > 解决方案 > 自定义验证器破坏密码更改表单

问题描述

我们正在尝试将自定义验证器添加到 Django 1.11.18 中的密码重置页面。下面是我们实施的简化版本。但是,在呈现密码重置页面的表单中似乎存在不寻常的副作用。我期待 3 个字段、old_passwordnew_password1new_password2但未new_password1在页面上呈现。我们使用了几乎所有默认的 Django 密码更改功能,如下面的views.py所示。如果从设置中删除验证器,则表单将按预期工作。

为什么验证器会破坏表单?

我的验证器.py

import re

from django.conf import settings
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _

class MyValidator(object):
    message = _("Password is not complex enough (%s)")
    code = "complexity"

    def __init__(self, complexities=None):
        self.complexities = complexities

    def validate(self, password, user=None):
        errors = []
        if password == '12345678':
           errors.append(_("Password must be 12345678"))

        if errors:
            raise ValidationError(self.message % (_(u'must contain ') + u', '.join(errors),),
                                  code=self.code)

    def get_help_text(self):
        return _(
            "Your password must contain 12345678"
        )

视图.py

class PasswordChangeView(views.PasswordChangeView):
    template_name = 'accounts/password_change.html'

设置.py

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        'OPTIONS': {
            'min_length': 8,
        }
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
    {
        'NAME': 'the.path.to.myvalidator.MyValidator',
    },
]

password_change.html

<form action="" method="post">
  {% csrf_token %}
  <div class="row mb20">
    <div class="col-md-6">
      <label class="pb5" for="{{ form.old_password.id_for_label }}"
        >{{ form.old_password.label }}</label
      >
      {{ form.old_password }} {{ form.old_password.errors }}
    </div>
  </div>

  <div class="row mb20">
    <div class="col-md-6">
      <label class="pb5" for="{{ form.new_password1.id_for_label }}"
        >{{ form.new_password1.label }}</label
      >
      {{ form.new_password1 }} {{ form.new_password1.errors }}
    </div>
  </div>

  <div class="row mb20">
    <div class="col-md-6">
      <label class="pb5" for="{{ form.new_password2.id_for_label }}"
        >{{ form.new_password2.label }}</label
      >
      {{ form.new_password2 }} {{ form.new_password2.errors }}
    </div>
  </div>

  <div class="clearfix mt20 text-right">
    <button type="submit" class="btn btn-sf-lightblue ml10">
      <span class="fa fa-floppy-o"></span> Change my password
    </button>
  </div>
</form>

标签: pythondjangodjango-forms

解决方案


我们意识到这是get_help_text函数的缩进错误。由于某种原因,该错误在 Django 中没有得到正确处理。追踪起来非常困难。


推荐阅读