Search code examples
pythondjangodjango-authenticationdjango-allauthdjango-users

Django allow spaces in username within UserChangeForm


Bit of a frustrating issue, there's a few similar questions but I can't seem to get any of the answers to work for me.

First of all: signup/login on my site is done exclusively through django-allauth. It has a setting ACCOUNT_USERNAME_VALIDATORS and this works fine for creating users - I just had to define a validator with this regex r'^[\w\.@+\- ]+$' and point the setting to it.

The issue is if I try to edit an existing user in the admin (for example to give them permissions), I get an error on save that the username field is invalid because of spaces. I've tried a couple of things like this method from the django docs:

from django.contrib.auth.models import User
from django.contrib.auth.validators import UnicodeUsernameValidator

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

class MyUser(User):
    username_validator = MyValidator()

class Meta:
    proxy = True  

And I've also tried overriding the UserChangeForm in my admin.py:

class MyUserChangeForm(UserChangeForm):
    username = forms.RegexField(
        label='Username',
        max_length=30,
        regex=r'^[\w\.@+\- ]+$',
        help_text = 'Required. 30 characters or fewer. Alphanumeric characters only (letters, digits, hyphens and underscores).')


class CustomUserAdmin(UserAdmin):
    form = MyUserChangeForm

admin.site.unregister(User)
admin.site.register(User, CustomUserAdmin)

But no luck with either. I don't get any errors but I still can't save changes to users with spaces in their usernames. I can't help but feel I'm missing something silly, from other answers it seems this should be fairly straightforward.


Solution

  • It seems based on this bug report that the username_validator setting doesn't work as intended - although that bug is old and the docs for 2.0 still provide this method, I'm assuming it hasn't been fixed as I've tried everything.

    Ultimately I'm going to bite the bullet and migrate to a custom user model, I should have done it from the get go but luckily I'm just implementing django all-auth as my exclusive sign in method and planned on dropping existing users anyways so hopefully the migration shouldn't be too much trouble.

    EDIT: For anyone else who runs into this, I highly recommend switching to custom user model. It's not as scary to switch mid-project as the docs make it sound.