views:

239

answers:

2

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?

+1  A: 

There is no straightforward way to revert back to old behavior.

The easiest way to handle this would be to enforce client and server side validation of usernames according to your demands. django-registration is not an actively developed component, I wouldn't count on anything coming from that direction. Just add some extra validation on your side.

To quote Jacob on this matter:

[...] another common request is to allow the use of email addresses as usernames.

Custom registration/signup forms can deal with further restrictions.

Yuval A
django-registration isn't actively developed? I thought ubernostrum just put a ton of work into a major refactoring, providing customizable back-ends, etc. That's a shame to hear - I use it on every project.I actually found a way to make this work! Answer below. Thanks Yuval.
shacker
A: 

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   
shacker