diff --git a/django/contrib/auth/tests/custom_user.py b/django/contrib/auth/tests/custom_user.py
index 8cc57d4..e4ac8bc 100644
a
|
b
|
class IsActiveTestUser1(AbstractBaseUser):
|
144 | 144 | app_label = 'auth' |
145 | 145 | |
146 | 146 | # the is_active attr is provided by AbstractBaseUser |
| 147 | |
| 148 | |
| 149 | class CustomUserNonUniqueUsername(AbstractBaseUser): |
| 150 | username =models.CharField(max_length=30) |
| 151 | |
| 152 | USERNAME_FIELD = 'username' |
| 153 | |
| 154 | class Meta: |
| 155 | app_label = 'auth' |
diff --git a/django/contrib/auth/tests/management.py b/django/contrib/auth/tests/management.py
index 42f14d6..67708fc 100644
a
|
b
|
from django.contrib.auth.tests import CustomUser
|
9 | 9 | from django.contrib.auth.tests.utils import skipIfCustomUser |
10 | 10 | from django.core.management import call_command |
11 | 11 | from django.core.management.base import CommandError |
| 12 | from django.db.models.loading import get_app |
12 | 13 | from django.test import TestCase |
13 | 14 | from django.test.utils import override_settings |
14 | 15 | from django.utils import six |
… |
… |
class CreatesuperuserManagementCommandTestCase(TestCase):
|
170 | 171 | self.assertEqual(CustomUser._default_manager.count(), 0) |
171 | 172 | |
172 | 173 | |
| 174 | class CustomUserModelValidationTestCase(TestCase): |
| 175 | @override_settings(AUTH_USER_MODEL='auth.CustomUserNonUniqueUsername') |
| 176 | def test_username_non_unique(self): |
| 177 | """ |
| 178 | A non-unique USERNAME_FIELD should raise a model validation error. |
| 179 | """ |
| 180 | from django.core.management.validation import get_validation_errors |
| 181 | new_io = StringIO() |
| 182 | get_validation_errors(new_io, get_app('auth')) |
| 183 | self.assertIn("The USERNAME_FIELD must be indexed as unique", new_io.getvalue()) |
| 184 | |
173 | 185 | class PermissionDuplicationTestCase(TestCase): |
174 | 186 | |
175 | 187 | def setUp(self): |
diff --git a/django/core/management/validation.py b/django/core/management/validation.py
index f49a3c2..ab47f3b 100644
a
|
b
|
def get_validation_errors(outfile, app=None):
|
54 | 54 | # Check that the USERNAME FIELD isn't included in REQUIRED_FIELDS. |
55 | 55 | if cls.USERNAME_FIELD in cls.REQUIRED_FIELDS: |
56 | 56 | e.add(opts, 'The field named as the USERNAME_FIELD should not be included in REQUIRED_FIELDS on a swappable User model.') |
| 57 | if not opts.get_field(cls.USERNAME_FIELD).unique: |
| 58 | e.add(opts, 'The USERNAME_FIELD must be indexed as unique (unique=True in the field parameters).') |
57 | 59 | |
58 | 60 | # Model isn't swapped; do field-specific validation. |
59 | 61 | for f in opts.local_fields: |