Loading django/contrib/auth/models.py +4 −0 Original line number Diff line number Diff line Loading @@ -344,6 +344,10 @@ class AbstractUser(AbstractBaseUser, PermissionsMixin): verbose_name_plural = _('users') abstract = True def clean(self): super(AbstractUser, self).clean() self.email = self.__class__.objects.normalize_email(self.email) def get_full_name(self): """ Returns the first_name plus the last_name, with a space in between. Loading docs/releases/1.11.txt +5 −0 Original line number Diff line number Diff line Loading @@ -293,6 +293,11 @@ Miscellaneous <django.db.models.Model.validate_unique>` no longer checks empty strings for uniqueness as the database interprets the value as ``NULL``. * If you subclass :class:`.AbstractUser` and override ``clean()``, be sure it calls ``super()``. :meth:`.BaseUserManager.normalize_email` is called in a new :meth:`.AbstractUser.clean` method so that normalization is applied in cases like model form validation. .. _deprecated-features-1.11: Features deprecated in 1.11 Loading docs/topics/auth/customizing.txt +13 −1 Original line number Diff line number Diff line Loading @@ -692,6 +692,18 @@ The following attributes and methods are available on any subclass of Returns an HMAC of the password field. Used for :ref:`session-invalidation-on-password-change`. :class:`~models.AbstractUser` subclasses :class:`~models.AbstractBaseUser`: .. class:: models.AbstractUser .. method:: clean() .. versionadded:: 1.11 Normalizes the email by calling :meth:`.BaseUserManager.normalize_email`. If you override this method, be sure to call ``super()`` to retain the normalization. You should also define a custom manager for your ``User`` model. If your ``User`` model defines ``username``, ``email``, ``is_staff``, ``is_active``, ``is_superuser``, ``last_login``, and ``date_joined`` fields the same as Loading Loading @@ -759,7 +771,7 @@ Extending Django's default ``User`` If you're entirely happy with Django's :class:`~django.contrib.auth.models.User` model and you just want to add some additional profile information, you could simply subclass ``django.contrib.auth.models.AbstractUser`` and add your simply subclass :class:`django.contrib.auth.models.AbstractUser` and add your custom profile fields, although we'd recommend a separate model as described in the "Model design considerations" note of :ref:`specifying-custom-user-model`. ``AbstractUser`` provides the full implementation of the default Loading tests/auth_tests/test_models.py +5 −0 Original line number Diff line number Diff line Loading @@ -194,6 +194,11 @@ class AbstractUserTestCase(TestCase): user2 = User.objects.create_user(username='user2') self.assertIsNone(user2.last_login) def test_user_clean_normalize_email(self): user = User(username='user', password='foo', email='foo@BAR.com') user.clean() self.assertEqual(user.email, 'foo@bar.com') def test_user_double_save(self): """ Calling user.save() twice should trigger password_changed() once. Loading Loading
django/contrib/auth/models.py +4 −0 Original line number Diff line number Diff line Loading @@ -344,6 +344,10 @@ class AbstractUser(AbstractBaseUser, PermissionsMixin): verbose_name_plural = _('users') abstract = True def clean(self): super(AbstractUser, self).clean() self.email = self.__class__.objects.normalize_email(self.email) def get_full_name(self): """ Returns the first_name plus the last_name, with a space in between. Loading
docs/releases/1.11.txt +5 −0 Original line number Diff line number Diff line Loading @@ -293,6 +293,11 @@ Miscellaneous <django.db.models.Model.validate_unique>` no longer checks empty strings for uniqueness as the database interprets the value as ``NULL``. * If you subclass :class:`.AbstractUser` and override ``clean()``, be sure it calls ``super()``. :meth:`.BaseUserManager.normalize_email` is called in a new :meth:`.AbstractUser.clean` method so that normalization is applied in cases like model form validation. .. _deprecated-features-1.11: Features deprecated in 1.11 Loading
docs/topics/auth/customizing.txt +13 −1 Original line number Diff line number Diff line Loading @@ -692,6 +692,18 @@ The following attributes and methods are available on any subclass of Returns an HMAC of the password field. Used for :ref:`session-invalidation-on-password-change`. :class:`~models.AbstractUser` subclasses :class:`~models.AbstractBaseUser`: .. class:: models.AbstractUser .. method:: clean() .. versionadded:: 1.11 Normalizes the email by calling :meth:`.BaseUserManager.normalize_email`. If you override this method, be sure to call ``super()`` to retain the normalization. You should also define a custom manager for your ``User`` model. If your ``User`` model defines ``username``, ``email``, ``is_staff``, ``is_active``, ``is_superuser``, ``last_login``, and ``date_joined`` fields the same as Loading Loading @@ -759,7 +771,7 @@ Extending Django's default ``User`` If you're entirely happy with Django's :class:`~django.contrib.auth.models.User` model and you just want to add some additional profile information, you could simply subclass ``django.contrib.auth.models.AbstractUser`` and add your simply subclass :class:`django.contrib.auth.models.AbstractUser` and add your custom profile fields, although we'd recommend a separate model as described in the "Model design considerations" note of :ref:`specifying-custom-user-model`. ``AbstractUser`` provides the full implementation of the default Loading
tests/auth_tests/test_models.py +5 −0 Original line number Diff line number Diff line Loading @@ -194,6 +194,11 @@ class AbstractUserTestCase(TestCase): user2 = User.objects.create_user(username='user2') self.assertIsNone(user2.last_login) def test_user_clean_normalize_email(self): user = User(username='user', password='foo', email='foo@BAR.com') user.clean() self.assertEqual(user.email, 'foo@bar.com') def test_user_double_save(self): """ Calling user.save() twice should trigger password_changed() once. Loading