Search code examples
djangoregistration

Disabling email-style usernames in Django 1.2 with django-registration


Django 1.2 allows usernames to take the form of an email address.

Changed in Django 1.2: Usernames may now contain @, +, . and - characters

I know that's a much-requested feature, but what if you don't want the new behavior? It makes for messy usernames in profile URLs and seems to break django-registration (if a user registers an account with an email-style username, the link in the django-registration activation email returns 404).

Does anyone have a recipe for restoring the old behavior and disabling email-style usernames?


Solution

  • django-registration actually wasn't the problem here. The problem was that I had subclassed its RegistrationForm, redefining the username field with new help_text. In so doing, I had prevented it from using its own regex field. To fix this, I had to pull a few bits and pieces from RegistrationForm into my EnhancedRegistrationForm subclass.

    Note the regex line, which mirrors the old-style username character restrictions (which is what I want).

    from registration.forms import RegistrationForm   
    
    # Carry these over from RegistrationForm - needed in the form definition below
    attrs_dict = {'class': 'required'}
    from django.utils.translation import ugettext_lazy as _
    
    class EnhancedRegistrationForm(RegistrationForm):
        first_name = forms.CharField(label='first name', max_length=30, required=True)
        last_name = forms.CharField(label='last name', max_length=30, required=True)    
        username = forms.RegexField(regex=r'^\w+$',
            max_length=30,
            widget=forms.TextInput(attrs=attrs_dict),
            help_text='Email addresses cannot be used as usernames.', 
            required=True,
            label=_("Username"),
            error_messages={'invalid':"You cannot use an email address as a username, sorry."})    
    
        class Meta:
            fields = ('first_name','last_name','username','email','password1','password2')  
    
    
        def save(self, *args, **kwargs):
            """
            Overriding save, so call the parent form save and return the new_user
            object.
            """
            new_user = super(EnhancedRegistrationForm, self).save(*args, **kwargs) 
            new_user.first_name = self.cleaned_data['first_name']
            new_user.last_name = self.cleaned_data['last_name']
            new_user.save()
            return new_user