I am trying to add custom password validation to the create user and change password admin forms. I did not see anything in the django docs about how to do this. I found this post on SO: Enforcing password strength requirements with django.contrib.auth.views.password_change, which gives 2 solutions. I tried both, but neither worked for me.
Here's what I have now in my apps 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)
But what I can't figure out is how do I get MySetPasswordForm to be used.
I've tried a few different things. First I did this:
class UserAdmin(UserAdmin):
form = MySetPasswordForm
# Re-register UserAdmin
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
And I got this error:
<class 'elex_apis.energy.webservice.admin.UserAdmin'>: (admin.E016) The value of 'form' must inherit from 'BaseModelForm'.
So then I changed MySetPasswordForm to inherit from BaseModelForm and then I got this error:
__init__() missing 1 required positional argument: 'user'
So then I added the user param so now MySetPasswordForm looked like this:
class MySetPasswordForm(BaseModelForm):
def __init__(self, user, *args, **kwargs):
super(MySetPasswordForm, self).__init__(user, *args, **kwargs)
self.fields['password1'].validators.append(validate_password_strength)
But I still got the same error as before.
I can't believe it's this hard to add a password validator. It must be a very common need, so clearly I must be missing something simple. Can anyone please provide some assistance here.
How To Create Your Own Django Password Validator. If you have more specific needs, you can create your own validators. To do so, simply create your own classes based on object and raise a ValidationError if the entered password fails. class NumberValidator(object): def validate(self, password, user=None): if not re.
validate(self, password, user=None) : validate a password. Return None if the password is valid, or raise a ValidationError with an error message if the password is not valid. You must be able to deal with user being None - if that means your validator can't run, return None for no error.
The Django's Forms The above form has two inputs - a text field named username (the name attribute in the html input field is what determines the name of input field) and a password field named password - and a submit button. The form uses POST method to submit form data to server.
The easiest way is to inherit the original UserAdmin
and just override the change_password_form
.
Example:
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With