【问题标题】:override password_validation messages覆盖密码验证消息
【发布时间】:2018-01-28 22:11:31
【问题描述】:

我使用 UserCreationForm 创建新用户。

from django.contrib.auth.forms import UserCreationForm

class RegistrationForm(UserCreationForm):
      class Meta:
       model = User
       fields = ['username', 'first_name', 'last_name', 'email',  'is_active']

UserCreationForm 自动添加两个字段(Password1Password2)。 如果密码太短,那么它会引发一个错误,告诉你。或者如果它太简单或太常见。它是通过django.contrib.auth.password_validation 完成的。

我想知道是否可以覆盖这些错误的消息。

现在密码验证的源代码是:

def validate(self, password, user=None):
    if len(password) < self.min_length:
        raise ValidationError(
            ungettext(
                "This password is too short. It must contain at least %(min_length)d character.",
                "This password is too short. It must contain at least %(min_length)d characters.",
                self.min_length
            ),
            code='password_too_short',
            params={'min_length': self.min_length},
        )

但是当我尝试在表单定义中使用此代码来覆盖此错误消息时,标签会更改,但 error_messages 保持不变:

password1 = forms.CharField(label='New Label', error_messages={'password_too_short': 'My error message for too short passwords'})

我做错了什么?

【问题讨论】:

  • 尝试仅将'password_too_short': ... 重命名为'too_short': ...
  • 不起作用:(

标签: django django-authentication


【解决方案1】:

对于那些只想更改验证消息的人来说,我找到了一个更好的解决方案,只需继承 @Gustavo 指定的类,并将密码验证设置变量替换为您自己指定的自定义分类

AUTH_PASSWORD_VALIDATORS = [
{
    'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
    'NAME': 'apps.user.validators.MinimumLengthValidatorCustom',
    # 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
    'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
    'NAME': 'apps.user.validators.NumericPasswordValidatorCustom',
    # 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},

]

【讨论】:

    【解决方案2】:

    更新:子类化而不是复制/粘贴可能是更好的解决方案。见gustavo's answer

    有关类似说明,请参阅 How to use custom password validators beside the django auth password validators?

    我一直在寻找相同的东西,但我认为没有任何方法可以从表单级别更改密码验证器上的错误消息。您可能最终不得不编写自己的自定义验证器,然后将其包含在您的 AUTH_PASSWORD_VALIDATORS 中的 settings.py 中(这就是我所做的)。我是这样做的:

    1. 转到 django 的内置密码验证器并复制 MinimumLengthValidator 代码。这是链接:https://docs.djangoproject.com/en/2.0/_modules/django/contrib/auth/password_validation/#MinimumLengthValidator

    2. 在您选择的应用程序中创建一个 python 文件(我选择了我的基础应用程序)并为其命名(我的是 custom_validators.py) 我的看起来像这样:

        from django.utils.translation import ngettext  # https://docs.python.org/2/library/gettext.html#gettext.ngettext
        from django.core.exceptions import ValidationError
    
        # https://docs.djangoproject.com/en/2.0/_modules/django/contrib/auth/password_validation/#MinimumLengthValidator
        class MyCustomMinimumLengthValidator(object):
            def __init__(self, min_length=8):  # put default min_length here
                self.min_length = min_length
    
            def validate(self, password, user=None):
                if len(password) < self.min_length:
                    raise ValidationError(
                        ngettext(
                            # silly, I know, but if your min length is one, put your message here
                            "This password is too short. It must contain at least %(min_length)d character.",
                            # if it's more than one (which it probably is) put your message here
                            "This password is too short. It must contain at least %(min_length)d characters.",
                            self.min_length
                        ),
                    code='password_too_short',
                    params={'min_length': self.min_length},
                    )
    
            def get_help_text(self):
                return ngettext(
                    # you can also change the help text to whatever you want for use in the templates (password.help_text)
                    "Your password must contain at least %(min_length)d character.",
                    "Your password must contain at least %(min_length)d characters.",
                    self.min_length
                ) % {'min_length': self.min_length}
    

    3.settings.py 中,注释掉AUTH_PASSWORD_VALIDATORS 中的以下行:

        # {
        #     'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        # },
    

    并添加以下行:

    {
        'NAME': 'base.custom_validators.MyCustomMinimumLengthValidator',
                # app_name.file_name.validator_name
    },
    

    现在,每当您运行 validate()form.is_valid()(也运行 validate())时,您的密码将通过您的新自定义密码验证器,而不是 django 的默认密码验证器。这可能需要一些调整,但您可能会为所有 django 的默认验证器执行此操作。

    希望有帮助!

    【讨论】:

      【解决方案3】:

      你也可以使用Django内置的i18n:

      1.创建文件&lt;PROJECT ROOT&gt;/locale/en/LC_MESSAGES/django.po

      msgid "This password is entirely numeric."
      msgstr "The password should contain both letters and numbers."
      

      2.settings.py添加

      LOCALE_PATHS = (
          os.path.join(BASE_DIR, 'locale'),
      )
      LANGUAGE_CODE = 'en-us'
      

      3.编译消息获取django.mo文件

      django-admin compilemessages
      

      然后,消息“密码应包含字母和数字”。将显示而不是“此密码完全是数字。”。

      通过这种方式,您可以更改所有标准消息。

      【讨论】:

      • 无法在 Django 1.11 上重现。我需要运行 django-admin makemessages -l en -e *.py 吗?我也尝试过运行它,但没有成功。
      • django-admin makemessages 是必需的。相反,运行django-admin compilemessages
      【解决方案4】:

      我找到了更好的解决方案:

      不需要替换类的所有代码,继承类MinimumLengthValidator并修改需要的定义就足够了。在这种情况下 validate 和 get_help_text。

      from django.contrib.auth.password_validation import MinimumLengthValidator
      from django.core.exceptions import ValidationError
      from django.utils.translation import ngettext
      
      # https://docs.djangoproject.com/en/2.0/_modules/django/contrib/auth/password_validation/#MinimumLengthValidator
      
      
      class MinimumLengthValidator(MinimumLengthValidator):
          # update this definition with your custom messages
          def validate(self, password, user=None):
              if len(password) < self.min_length:
                  raise ValidationError(
                      ngettext(
                          "This password is too short. It must contain at least %(min_length)d character.",
                          "This password is too short. It must contain at least %(min_length)d characters.",
                          self.min_length
                      ),
                  ),
                  code='password_too_short',
                  params={'min_length': self.min_length},
              )
      
          # update this definition with your custom messages
          def get_help_text(self):
             return ngettext(
                 "Your password must contain at least %(min_length)d character.",
                 "Your password must contain at least %(min_length)d characters.",
                 self.min_length
             ) % {'min_length': self.min_length}
      

      我希望这可以帮助其他人解决这个问题。

      【讨论】:

      • 它对我不起作用我做了同样的事情它仍然在 django.contrib.auth.password_validation 中显示消息你能帮我吗?
      猜你喜欢
      • 2018-01-31
      • 1970-01-01
      • 2020-01-17
      • 1970-01-01
      • 1970-01-01
      • 2014-08-01
      • 2014-04-04
      • 2017-09-06
      • 2012-02-02
      相关资源
      最近更新 更多