diff --git a/django/contrib/auth/migrations/0008_alter_user_username_max_length.py b/django/contrib/auth/migrations/0008_alter_user_username_max_length.py new file mode 100644 index 00000000000..56705fa58f3 --- /dev/null +++ b/django/contrib/auth/migrations/0008_alter_user_username_max_length.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('auth', '0007_alter_validators_add_error_messages'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='username', + field=models.CharField( + error_messages={'unique': 'A user with that username already exists.'}, + help_text='Required. 254 characters or fewer. Letters, digits and @/./+/-/_ only.', + max_length=254, + unique=True, + validators=[ + django.core.validators.RegexValidator( + '^[\\w.@+-]+$', 'Enter a valid username. ' + 'This value may contain only letters, numbers and @/./+/-/_ characters.' + ), + ], + verbose_name='username', + ), + ), + ] diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py index 070d7d44356..dfa76977d7b 100644 --- a/django/contrib/auth/models.py +++ b/django/contrib/auth/models.py @@ -303,9 +303,9 @@ class AbstractUser(AbstractBaseUser, PermissionsMixin): """ username = models.CharField( _('username'), - max_length=30, + max_length=254, unique=True, - help_text=_('Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.'), + help_text=_('Required. 254 characters or fewer. Letters, digits and @/./+/-/_ only.'), validators=[ validators.RegexValidator( r'^[\w.@+-]+$', diff --git a/docs/ref/contrib/auth.txt b/docs/ref/contrib/auth.txt index 6cbfd88ac6f..6ca25813976 100644 --- a/docs/ref/contrib/auth.txt +++ b/docs/ref/contrib/auth.txt @@ -21,9 +21,13 @@ Fields .. attribute:: username - Required. 30 characters or fewer. Usernames may contain alphanumeric, + Required. 254 characters or fewer. Usernames may contain alphanumeric, ``_``, ``@``, ``+``, ``.`` and ``-`` characters. + .. versionchanged:: 1.10 + + The ``max_length`` increased from 30 to 254 characters. + .. attribute:: first_name Optional. 30 characters or fewer. diff --git a/docs/releases/1.10.txt b/docs/releases/1.10.txt index 602e34a6f98..b291dcfd41a 100644 --- a/docs/releases/1.10.txt +++ b/docs/releases/1.10.txt @@ -258,6 +258,36 @@ to its proxied concrete class. This inconsistency was fixed by returning the full set of fields pointing to a concrete class or one of its proxies in both cases. +:attr:`AbstractUser.username ` ``max_length`` increased to 254 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A migration for :attr:`django.contrib.auth.models.User.username` is included. +If you have a custom user model inheriting from ``AbstractUser``, you'll need +to generate and apply a database migration for your user model. + +If you want to preserve the 30 character limit for usernames, use a custom form +when creating a user or changing usernames:: + + from django.contrib.auth.forms import UserCreationForm + + class MyUserCreationForm(UserCreationForm): + username = forms.CharField( + max_length=30, + help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', + ) + +If you wish to keep this restriction in the admin, set ``UserAdmin.add_form`` +to use this form:: + + from django.contrib.auth.admin import UserAdmin + from django.contrib.auth.models import User + + class MyUserAdmin(UserAdmin): + add_form = MyUserCreationForm + + admin.site.unregister(User) + admin.site.register(User, MyUserAdmin) + Miscellaneous ~~~~~~~~~~~~~