3👍
If you aren’t trying to modify the fields on the default User class, the other Jonathan’s answer for post 1.10 is good except for a couple small mistakes.
username_validator = MyValidator
needs to beusername_validator = MyValidator()
or the validator will fail silently and allow anything.- The dash should be the last character in the brackets or escaped (otherwise it will act as a range).
- A space should be used instead of the
\s
character, which would allow any whitespace (including tabs and newlines).
The final code looks like:
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 # If no new field is added.
(simply replace UnicodeUsernameValidator
with ASCIIUsernameValidator
if using Python 2). Note that the dot is within brackets, so it doesn’t need to be escaped.
If you are modifying the fields on your User class, you are probably subclassing AbstractUser
and you can’t use proxy = True
. This means the username
field on AbstractUser
will use the username_validator
declared on AbstractUser
, not yours. To fix this, you pretty much have to re-declare username
on your model, like so:
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.validators import UnicodeUsernameValidator
from django.utils.translation import ugettext_lazy as _
class MyValidator(UnicodeUsernameValidator):
regex = r'^[\w.@+\- ]+$'
class MyUser(AbstractUser):
username_validator = MyValidator()
username = models.CharField(
_('username'),
max_length=150,
unique=True,
help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
validators=[username_validator],
error_messages={
'unique': _("A user with that username already exists."),
},
)
Make sure you run makemigrations and migrate afterwards.
I’ve tried a number of ways to change the validators on username after it has already been declared, but haven’t had any luck, so it looks like this is the best way for now.
1👍
You’ll need to modify the user where the validator exists. The following code should work for Django 1.9.
With this user below you should be able to use MyUser
instead of User
for the form that you wrote.
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.
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 username_validator
and you’ll have to override that. You can read more about it in the manual.
If you’re using python2 you’ll have to override ASCIIUsernameValidator
or if you using python3 you’ll have to override UnicodeUsernameValidator
. For simplicity I’ll assume that you’re using python3. You can see the source code of the validation here.
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.
- [Django]-How to list all the files of a custom directory
- [Django]-Best JSON library to get JSON data for Django?
- [Django]-Django 1.4 – Keeping track of multiple queries and pagination
- [Django]-Lower() was called on None
- [Django]-Google application engine, maximum number of static files?