How can I allow spaces in a Django username regex?
<p>I am trying to allow spaces to be accepted into the username field of the default django.contrib.auth.models User, other people have asked directly or similar questions before: <a href="http://stackoverflow.com/questions/19911087/how-can-i-allow-spaces-in-a-django-username">Here</a>, <a href="http://stackoverflow.com/questions/1214453/allowing-the-character-in-usernames-in-the-django-admin-interface">Here</a>, and <a href="http://stackoverflow.com/questions/9828177/django-auth-manipulate-model-fields-allow-space-in-usernames">Here</a>. I have tried to implement these suggestions however I cannot seem to find a good example of how to get this to work. </p>

<p>From what I understand I need to change the regex in the username field validator, to do this I can override the UserCreationForm from contrib.auth.forms to implement a different field for username and provide my own validation. (as suggested in <a href="http://stackoverflow.com/questions/9828177/django-auth-manipulate-model-fields-allow-space-in-usernames">this</a> answer). </p>

<p>How specifically do I do this?</p>

<p>for reference, this is currently what I am using as a signup form:</p>

<pre><code>class SignUpForm(forms.ModelForm):
    """
    This form class is for creating a player
    """
    username = forms.CharField(label='Gamertag', max_length=16, widget=forms.TextInput(attrs={'placeholder': 'Gamertag', 'class': 'form-input'}))
    email = forms.EmailField(label='email', widget=forms.TextInput(attrs={'placeholder': 'Email', 'class': 'form-input', 'type':'email'}))
    password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Password', 'class': 'form-input'}))

    class Meta:
        model = User
        fields = ['username',
                  'email',
                  'password']
        widgets = {
            'password': forms.PasswordInput(),
        }

    def clean_email(self):
        email = self.cleaned_data.get('email')
        username = self.cleaned_data.get('username')
        if email and User.objects.filter(email=email).exclude(username=username).count():
            raise forms.ValidationError(u'A user with that email already exists.')
        return email
</code></pre>

<p>You'll need to modify the user where the validator exists. The following code should work for Django 1.9. </p>

<p>With this user below you should be able to use <code>MyUser</code> instead of <code>User</code> for the form that you wrote.  </p>

<pre><code>from django.contrib.auth.models import AbstractUser
from django.core import validators

class MyUser(AbstractUser):
    validators=[
                validators.RegexValidator(
                    r'^[\w.@+-\s]+$',
                    _('Enter a valid username. This value may contain only '
                      'letters, numbers, spaces ' 'and @/./+/-/_ characters.')
                ),
            ],

    class Meta:
        proxy = True  # If no new field is added.
</code></pre>

<p>If you want to do it in Django 1.10 you'll have to change the code slightly. In Django 1.10 a new property was added <code>username_validator</code> and you'll have to override that. You can read more about it in the <a href="https://docs.djangoproject.com/en/1.10/ref/contrib/auth/#django.contrib.auth.models.User.username_validator" rel="nofollow">manual</a>. </p>

<p>If you're using python2 you'll have to override <code>ASCIIUsernameValidator</code> or if you using python3 you'll have to override <code>UnicodeUsernameValidator</code>. For simplicity I'll assume that you're using python3. You can see the source code of the validation <a href="https://github.com/django/django/blob/1.10.1/django/contrib/auth/validators.py#L19-L26" rel="nofollow">here</a>.</p>

<pre><code>from django.contrib.auth.models import User
from django.contrib.auth.validators import UnicodeUsernameValidator

class MyValidator(UnicodeUsernameValidator):
    regex = r'^[\w.@+-\s]+$'

class MyUser(User):
    username_validator = MyValidator

    class Meta:
        proxy = True  # If no new field is added.
</code></pre>

python django django-models django-forms django-admin