UsernameField (for clean error messages)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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

More like this

  1. Validation for 'unique' and 'unique_together' constraints (different version) by miracle2k 5 years, 11 months ago
  2. UKPhoneNumberField GB v3 (improved) by g1smd 9 months, 2 weeks ago
  3. Currency Fields with newforms by sago 6 years, 2 months ago
  4. restrict user access to modeladmin via metaclass by code_shogan 2 years, 3 months ago
  5. CleanCharField by DvD 5 years, 8 months ago

Comments

diverman (on August 11, 2009):

Look at RegexField...

#

davepeck (on August 12, 2009):

diverman: You missed the point. :-)

Sometimes you've got to return precise, friendly error messages. This is especially true when you want your users to actually have a shot at signing in. You could use a RegexField, and if it doesn't validate you could always display the same error message regardless of the root cause. Or you could use this class to get easier to understand fine-grained error messages for entered user names.

RegexField is not the solution to all the world's woes -- especially where human factors are involved.

#

(Forgotten your password?)