我使用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
会自动添加两个字段( Password1 和 Password2 )。
如果密码太短,则会引发错误,告诉它。或者,如果它太简单或常见。它是通过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'})
我做错了什么?
答案 0 :(得分:5)
有关类似说明,请参阅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的所有默认验证器执行此操作。
希望有所帮助!
答案 1 :(得分:3)
我找到了更好的解决方案:
不必替换该类的所有代码,只需继承类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}
我希望这可以帮助其他人解决这个问题。
答案 2 :(得分: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',
},
]
答案 3 :(得分:0)
您还可以使用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
此后,出现消息“密码应同时包含字母和数字。”将会显示,而不是“此密码完全是数字。”。
通过这种方式,您可以更改所有标准消息。