django 1.7中的自定义密码验证

Lar*_*ell 12 django django-admin django-authentication

我正在尝试向创建用户添加自定义密码验证并更改密码管理表单.我没有在django文档中看到有关如何执行此操作的任何内容.我在SO上发现了这篇文章:使用django.contrib.auth.views.password_change强制执行密码强度要求,它提供了2个解决方案.我试过了两个,但都没有为我工作.

这是我现在在我的应用程序admin.py中的内容:

def validate_password_strength(value):
    """Validates that a password is as least 10 characters long and has at least
    2 digits and 1 Upper case letter.
    """
    min_length = 10

    if len(value) < min_length:
        raise ValidationError(_('Password must be at least {0} characters '
                                'long.').format(min_length))

    # check for 2 digits
    if sum(c.isdigit() for c in value) < 2:
        raise ValidationError(_('Password must container at least 2 digits.'))

    # check for uppercase letter
    if not any(c.isupper() for c in value):
        raise ValidationError(_('Password must container at least 1 uppercase letter.'))

class MySetPasswordForm(SetPasswordForm):
    def __init__(self, *args, **kwargs):
        super(MySetPasswordForm, self).__init__(*args, **kwargs)
        self.fields['password1'].validators.append(validate_password_strength)
Run Code Online (Sandbox Code Playgroud)

但我无法弄清楚的是如何使用MySetPasswordForm.

我尝试了一些不同的东西.首先我这样做了:

class UserAdmin(UserAdmin):
    form = MySetPasswordForm

# Re-register UserAdmin
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
Run Code Online (Sandbox Code Playgroud)

我收到了这个错误:

<class 'elex_apis.energy.webservice.admin.UserAdmin'>: (admin.E016) The value of 'form' must inherit from 'BaseModelForm'.
Run Code Online (Sandbox Code Playgroud)

所以我改变了MySetPasswordForm继承BaseModelForm然后我收到了这个错误:

__init__() missing 1 required positional argument: 'user'
Run Code Online (Sandbox Code Playgroud)

那么我添加了用户参数,所以现在MySetPasswordForm看起来像这样:

class MySetPasswordForm(BaseModelForm):
    def __init__(self, user, *args, **kwargs):
        super(MySetPasswordForm, self).__init__(user, *args, **kwargs)
        self.fields['password1'].validators.append(validate_password_strength)
Run Code Online (Sandbox Code Playgroud)

但我仍然得到了和以前一样的错误.

我不敢相信添加密码验证器很难.这一定是一个非常普遍的需求,所以显然我必须错过一些简单的东西.有人可以在这里提供一些帮助.

Wol*_*lph 7

最简单的方法是继承原始文件,UserAdmin然后重写change_password_form.

例:

from django.contrib.auth import models as auth_models
from django.contrib.auth import admin as auth_admin
from django.contrib.auth import forms as auth_forms
from django.core.exceptions import ValidationError


def validate_password_strength(value):
    """Validates that a password is as least 10 characters long and has at least
    2 digits and 1 Upper case letter.
    """
    min_length = 10

    if len(value) < min_length:
        raise ValidationError(_('Password must be at least {0} characters '
                                'long.').format(min_length))

    # check for 2 digits
    if sum(c.isdigit() for c in value) < 2:
        raise ValidationError(_('Password must container at least 2 digits.'))

    # check for uppercase letter
    if not any(c.isupper() for c in value):
        raise ValidationError(_('Password must container at least 1 uppercase letter.'))

    return value


class AdminPasswordChangeForm(auth_forms.AdminPasswordChangeForm):
    def clean_password1(self):
        return validate_password_strength(self.cleaned_data['password1'])


class UserCreationForm(auth_forms.UserCreationForm):
    def clean_password1(self):
        return validate_password_strength(self.cleaned_data['password1'])


class UserAdmin(auth_admin.UserAdmin):
    change_password_form = AdminPasswordChangeForm
    add_form = UserCreationForm


# Re-register UserAdmin
admin.site.unregister(auth_models.User)
admin.site.register(auth_models.User, UserAdmin)
Run Code Online (Sandbox Code Playgroud)