Validate new users passwords in Django admin interface

China☆狼群 提交于 2019-12-25 03:13:11

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!