问题
There is one interesting moment in 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.
But in my Django app i am using only Django Admin interface with admin.ModelAdmin
.
When i am trying to create new user i can broke all the validators from AUTH_PASSWORD_VALIDATORS
.
How can i validate passwords on creating new users in Django admin interface using validators AUTH_PASSWORD_VALIDATORS
?
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',
}
回答1:
The docs you have linked to say:
By default, validators are used in the forms to reset or change passwords
For example, the UserAdmin
uses the UserCreationForm, which validates the passwords.
You have your own UserAdmin
and UserCreateForm
, so the passwords will not be validated unless you add this functionality.
Think carefully about whether you really need to override AbstractBaseUser
. If you override AbstractUser
instead, then it will be easier to use/extend the built in forms/model admins, and you won't have to implement password validation yourself.
回答2:
UPD from author of question:
For everyone with same problem: you need to add that function to 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)
来源:https://stackoverflow.com/questions/50878903/validate-new-users-passwords-in-django-admin-interface