在 Django 管理界面中验证新用户密码
Validate new users passwords in Django admin interface
Django documentation 中有一个有趣的时刻:
By default, validators are used in the forms to reset or change passwords and in the createsuperuser and changepassword management commands. Validators aren’t applied at the model level, for example in User.objects.create_user() and create_superuser(), because we assume that developers, not users, interact with Django at that level and also because model validation doesn’t automatically run as part of creating models.
但是在我的 Django 应用程序中,我只使用 Django 管理界面 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',
}
您链接的文档说:
By default, validators are used in the forms to reset or change passwords
例如,UserAdmin
使用 UserCreationForm
来验证密码。
您有自己的 UserAdmin
和 UserCreateForm
,因此除非您添加此功能,否则不会验证密码。
仔细考虑是否真的需要覆盖AbstractBaseUser
。如果您改写 AbstractUser
,那么 use/extend 内置 forms/model 管理员会更容易,并且您不必自己实施密码验证。
来自问题作者的更新:
对于遇到同样问题的每个人:您需要将该功能添加到 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)
Django documentation 中有一个有趣的时刻:
By default, validators are used in the forms to reset or change passwords and in the createsuperuser and changepassword management commands. Validators aren’t applied at the model level, for example in User.objects.create_user() and create_superuser(), because we assume that developers, not users, interact with Django at that level and also because model validation doesn’t automatically run as part of creating models.
但是在我的 Django 应用程序中,我只使用 Django 管理界面 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',
}
您链接的文档说:
By default, validators are used in the forms to reset or change passwords
例如,UserAdmin
使用 UserCreationForm
来验证密码。
您有自己的 UserAdmin
和 UserCreateForm
,因此除非您添加此功能,否则不会验证密码。
仔细考虑是否真的需要覆盖AbstractBaseUser
。如果您改写 AbstractUser
,那么 use/extend 内置 forms/model 管理员会更容易,并且您不必自己实施密码验证。
来自问题作者的更新:
对于遇到同样问题的每个人:您需要将该功能添加到 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)