我正在实现一个自定义密码验证程序,它引用管理员用户可以更改的数据库中的设置。一个简化的例子:
class ConfigurableMinimumLengthValidator(object):
def get_value(self):
return MyConfigModel.objects.first().password_minimum_length
def validate(self, password, user=None):
min_len = self.get_value()
if len(password) < min_len:
raise ValidationError("Password too short, must be > %s long." % min_len)
def get_help_text(self):
min_len = self.get_value()
return "Password must be > %s long." % min_len
Django在初始设置期间调用get_help_text(),这大致相当于在模块导入期间进行数据库调用。这导致了各种鸡和蛋的问题:
如果没有从settings.py中取出密码验证器,前两个就无法解决,因为错误发生在./manage.py migrate
和其他所有管理命令中。
起初我计划捕获这些异常并返回默认值;它会在实际验证期间再次查询。但是我不确定我是否已经考虑过所有可能的异常,我不想使用一个裸的except子句。
有更清洁的方法吗?一些懒惰的代理字符串对象,直到使用才被评估?还是一种检测Django仍在设置的方法?猴子修补安装程序以不调用get_help_text()直到以后?
答案 0 :(得分:-1)
您需要向验证器类添加init函数,并将参数作为settings.py
中的OPTIONS值传递给此函数。以下示例来自django.contrib.auth.password_validation
中MinimumLengthValidator的Django 1.11代码。它将min_length
作为参数传递:
<强> settings.py 强>
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
'OPTIONS': {
'min_length': 15,
}
},
]
<强> password_validation.py 强>
class MinimumLengthValidator(object):
"""
Validate whether the password is of a minimum length.
"""
def __init__(self, min_length=8):
self.min_length = min_length
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},
)
def get_help_text(self):
return ungettext(
"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}
来自https://github.com/django/django的Django代码 版权所有Django软件基金会和个人贡献者 SPDX-License-Identifier:BSD-3-Clause