import re from django import forms from django.forms import ValidationError from django.contrib.auth.models import User from django.utils.translation import ugettext_lazy as _ class UsernameField(forms.CharField): default_error_messages = { 'username_too_short': _(u'Usernames must be at least three characters long.'), 'username_too_long': _(u'Usernames can be at most thirty characters long.'), 'bad_username_start': _(u'Usernames must start with a letter from the alphabet.'), 'invalid_username': _(u'Usernames can only have letters, digits, and underscores.'), } MIN_USERNAME_SIZE = 3 MAX_USERNAME_SIZE = 30 def __init__(self, *args, **kwargs): super(UsernameField, self).__init__(*args, **kwargs) def clean(self, value): super_clean = super(UsernameField, self).clean(value) # We could do this all with one regular expression: # ^[A-za-z]\w{1,29}$ # but to be kind to our users we do it with increasingly # restrictive tests that give increasingly more detailed error feedback. if len(super_clean) < UsernameField.MIN_USERNAME_SIZE: raise ValidationError(self.error_messages['username_too_short']) if len(super_clean) > UsernameField.MAX_USERNAME_SIZE: raise ValidationError(self.error_messages['username_too_long']) if re.match(r'^[A-Za-z]', super_clean) is None: raise ValidationError(self.error_messages['bad_username_start']) if re.match(r'^[A-Za-z]\w+$', super_clean) is None: raise ValidationError(self.error_messages['invalid_username']) return super_clean