Django documentation中有一个有趣的时刻:
默认情况下,验证程序在表单中用于重置或更改密码以及createsuperuser和changepassword管理命令。验证程序不在模型级别应用,例如在User.objects.create_user()和create_superuser()中,因为我们假设开发人员而不是用户在该级别与Django交互,并且因为模型验证不会自动运行作为创建模型的一部分。
但在我的Django应用程序中,我只使用Django Admin界面admin.ModelAdmin
当我试图创建新用户时,我可以打破AUTH_PASSWORD_VALIDATORS
的所有验证器
如何使用验证器AUTH_PASSWORD_VALIDATORS
验证在Django管理界面中创建新用户的密码?
admin.py:
class UserCreateForm(ModelForm):
class Meta:
model = User
fields = ['username', 'password']
class UserAdmin(admin.ModelAdmin):
form = UserCreateForm
list_display = ('username')
def get_form(self, request, obj=None, change=False, **kwargs):
if change:
return self.change_form
return super(UserAdmin, self).get_form(request, obj, **kwargs)
def has_add_permission(self, request):
return True
def has_delete_permission(self, request, obj=None):
return False
def has_change_permission(self, request, obj=None):
return True
def save_model(self, request, obj, form, change):
if obj.pk:
orig_obj = User.objects.get(pk=obj.pk)
if obj.password != orig_obj.password:
obj.set_password(obj.password)
else:
obj.is_superuser = True
obj.set_password(obj.password)
obj.save()
models.py:
class User(AbstractBaseUser, PermissionsMixin):
USERNAME_FIELD = 'username'
username_validator = UnicodeUsernameValidator()
username = models.CharField(
max_length=150,
unique=True,
validators=[username_validator]
)
objects = UserManager()
managers.py:
class UserManager(BaseUserManager):
def create_user(self, username, password=None):
if not username:
raise ValueError('Users must have username assigned')
user = self.model(username=username)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, username, password=None):
user = self.create_user(username, password=password)
user.is_superuser = True
user.save(using=self._db)
return user
settings.py:
AUTH_USER_MODEL = 'users.User'
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
}
答案 0 :(得分:1)
您链接的文档说:
默认情况下,表单中使用验证器来重置或更改密码
例如,UserAdmin
使用UserCreationForm
验证密码。
您拥有自己的UserAdmin
和UserCreateForm
,因此除非您添加此功能,否则不会验证密码。
仔细考虑是否真的需要覆盖AbstractBaseUser
。如果您改写AbstractUser
,那么使用/扩展内置表单/模型管理员会更容易,而且您不必自己实施密码验证。
答案 1 :(得分:0)
来自问题作者的UPD:
对于遇到相同问题的每个人:您需要将该功能添加到UserCreateForm
:
def clean(self):
password = self.cleaned_data.get('password')
if password:
try:
password_validation.validate_password(password, self.instance)
except forms.ValidationError as error:
self.add_error('password', error)