覆盖password_validation消息

Phi*_*ski 1 django django-authentication

我使用UserCreationForm来创建新用户.

from django.contrib.auth.forms import UserCreationForm

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

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},
        )
Run Code Online (Sandbox Code Playgroud)

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

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

我究竟做错了什么?

kim*_*mbo 6

请参阅如何在django auth密码验证器旁边使用自定义密码验证器?对于类似的说明.

我一直在寻找相同的东西,我认为没有办法从表单级别更改密码验证器上的错误消息.您可能最终必须编写自己的自定义验证器,然后将其包含在您的AUTH_PASSWORD_VALIDATORSsettings.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}
Run Code Online (Sandbox Code Playgroud)

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

    # {
    #     'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    # },
Run Code Online (Sandbox Code Playgroud)

并添加以下行:

{
    'NAME': 'base.custom_validators.MyCustomMinimumLengthValidator',
            # app_name.file_name.validator_name
},
Run Code Online (Sandbox Code Playgroud)

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

希望有所帮助!


Gus*_*ría 6

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

不需要替换类的所有代码,继承类MinimumLengthValidator并修改需要的定义就足够了。在这种情况下验证和 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}
Run Code Online (Sandbox Code Playgroud)

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


小智 5

对于那些只想更改验证消息的人来说,我找到了更好的解决方案,只需继承@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',
},
Run Code Online (Sandbox Code Playgroud)

]