How to use custom password validators beside the django auth password validators?
django, passwords, python, registration, validation
Solution
So, as e4c5 mentioned, it is really simple and straightforward.
My CustomPasswordValidator looks like this:
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext as _
class CustomPasswordValidator():
def __init__(self, min_length=1):
self.min_length = min_length
def validate(self, password, user=None):
special_characters = "[~\!@#\$%\^&\*\(\)_\+{}\":;'\[\]]"
if not any(char.isdigit() for char in password):
raise ValidationError(_('Password must contain at least %(min_length)d digit.') % {'min_length': self.min_length})
if not any(char.isalpha() for char in password):
raise ValidationError(_('Password must contain at least %(min_length)d letter.') % {'min_length': self.min_length})
if not any(char in special_characters for char in password):
raise ValidationError(_('Password must contain at least %(min_length)d special character.') % {'min_length': self.min_length})
def get_help_text(self):
return ""
Just add it to the list of AUTH_PASSWORD_VALIDATORS in settings.py and that's it!
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
{ 'NAME': 'registration.validators.CustomPasswordValidator',
},]
Problem
As the question above mentioned, I will trying to use a certain extra rule to validate a password during the registration process. The extra rule should be that a password is validate if it has at least one digit, one letter and one special character. My approach to solute this problem I've created a file named validators.py. ``` from django.core.exceptions import ValidationError class CustomPasswortValidator: def validate(value): # check for digit if not any(char.isdigit() for char in value): raise ValidationError(_('Password must contain at least 1 digit.')) # check for letter if not any(char.isalpha() for char in value): raise ValidationError(_('Password must contain at least 1 letter.')) # check for special character special_characters = "[~\!@#\$%\^&\*\(\)_\+{}\":;'\[\]]" if not any(char in special_characters for char in value): raise ValidationError(_('Password must contain at least 1 letter.')) ``` My custom registration form looks like this: ``` from django import forms from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User class RegistrationForm(UserCreationForm): first_name = forms.CharField(max_length=30, required=False, help_text='Optional.') last_name = forms.CharField(max_length=30, required=False, help_text='Optional.') email = forms.EmailField(max_length=254, help_text='Required. Inform a valid email address.') class Meta: model = User fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2', ) ``` I don't get it how I tell django, that my custom password validator should be use beside the django AUTH_PASSWORD_VALIDATORS.