diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py index 78fd7fbb5cd..971621d9c74 100644 --- a/django/contrib/auth/models.py +++ b/django/contrib/auth/models.py @@ -146,7 +146,7 @@ class UserManager(BaseUserManager): extra_fields.setdefault('is_superuser', False) return self._create_user(username, email, password, **extra_fields) - def create_superuser(self, username, email, password, **extra_fields): + def create_superuser(self, username, email=None, password=None, **extra_fields): extra_fields.setdefault('is_staff', True) extra_fields.setdefault('is_superuser', True) diff --git a/docs/ref/contrib/auth.txt b/docs/ref/contrib/auth.txt index e3dda3045fb..666208b28c3 100644 --- a/docs/ref/contrib/auth.txt +++ b/docs/ref/contrib/auth.txt @@ -282,11 +282,15 @@ Manager methods See :ref:`Creating users ` for example usage. - .. method:: create_superuser(username, email, password, **extra_fields) + .. method:: create_superuser(username, email=None, password=None, **extra_fields) Same as :meth:`create_user`, but sets :attr:`~models.User.is_staff` and :attr:`~models.User.is_superuser` to ``True``. + .. versionchanged:: 3.0 + + The ``email`` and ``password`` parameters were made optional. + ``AnonymousUser`` object ======================== diff --git a/docs/topics/auth/customizing.txt b/docs/topics/auth/customizing.txt index afc9bb3e62a..53dc14ebd88 100644 --- a/docs/topics/auth/customizing.txt +++ b/docs/topics/auth/customizing.txt @@ -746,20 +746,17 @@ providing two additional methods: # create user here ... - .. method:: models.CustomUserManager.create_superuser(*username_field*, password, **other_fields) + .. method:: models.CustomUserManager.create_superuser(*username_field*, password=None, **other_fields) The prototype of ``create_superuser()`` should accept the username field, plus all required fields as arguments. For example, if your user model uses ``email`` as the username field, and has ``date_of_birth`` as a required field, then ``create_superuser`` should be defined as:: - def create_superuser(self, email, date_of_birth, password): + def create_superuser(self, email, date_of_birth, password=None): # create superuser here ... - Unlike ``create_user()``, ``create_superuser()`` *must* require the - caller to provide a password. - For a :class:`~.ForeignKey` in :attr:`.USERNAME_FIELD` or :attr:`.REQUIRED_FIELDS`, these methods receive the value of the :attr:`~.ForeignKey.to_field` (the :attr:`~django.db.models.Field.primary_key` @@ -1044,7 +1041,7 @@ authentication app:: user.save(using=self._db) return user - def create_superuser(self, email, date_of_birth, password): + def create_superuser(self, email, date_of_birth, password=None): """ Creates and saves a superuser with the given email, date of birth and password. diff --git a/tests/auth_tests/test_basic.py b/tests/auth_tests/test_basic.py index c1b7e60455d..9e0d8e863ed 100644 --- a/tests/auth_tests/test_basic.py +++ b/tests/auth_tests/test_basic.py @@ -73,6 +73,22 @@ class BasicTestCase(TestCase): self.assertTrue(super.is_active) self.assertTrue(super.is_staff) + def test_superuser_no_email_or_password(self): + cases = [ + {}, + {'email': ''}, + {'email': None}, + {'password': None}, + ] + for i, kwargs in enumerate(cases): + with self.subTest(**kwargs): + superuser = User.objects.create_superuser( + 'super{}'.format(i), + **kwargs + ) + self.assertEqual(superuser.email, '') + self.assertFalse(superuser.has_usable_password()) + def test_get_user_model(self): "The current user model can be retrieved" self.assertEqual(get_user_model(), User)