代码之家  ›  专栏  ›  技术社区  ›  Philipp Chapkovski

覆盖password\u验证消息

  •  4
  • Philipp Chapkovski  · 技术社区  · 7 年前

    我使用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 自动添加两个字段( 密码1 密码2 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},
            )
    

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

    4 回复  |  直到 7 年前
        1
  •  9
  •   kimbo    5 年前

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

    How to use custom password validators beside the django auth password validators?

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

    1. 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}
    

    在里面 ,在您的 AUTH\u PASSWORD\u验证器 :

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

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

    validate() form.is_valid() (这也适用于 )您的密码将通过新的自定义密码验证器,而不是django的默认密码验证器。这可能需要一些调整,但您可能需要对django的所有默认验证器进行调整。

    希望这有帮助!

        2
  •  7
  •   Gustavo Santamaría    6 年前

    不必替换类的所有代码,只需继承类MinimumLengthValidator并修改所需的定义即可。在这种情况下,验证并获取_help_文本。

    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}
    

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

        3
  •  4
  •   Pankaj78691    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',
    },
    

    ]

        4
  •  1
  •   dtatarkin    6 年前

    也可以使用Django的内置 i18n

    1. <PROJECT ROOT>/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