From 5df0ff4155d2ee3192768e8f7f75b546f98c3f77 Mon Sep 17 00:00:00 2001 From: Josh Schneier Date: Wed, 19 Apr 2017 13:02:55 -0400 Subject: [PATCH] Fixed #28089 -- Removed requirement to implement get_short_name() and get_full_name() in AbstractBaseUser subclasses. --- django/contrib/auth/base_user.py | 6 --- docs/releases/2.0.txt | 7 +++ docs/topics/auth/customizing.txt | 44 +++++++------------ tests/auth_tests/models/custom_permissions.py | 6 --- tests/auth_tests/models/custom_user.py | 6 --- 5 files changed, 24 insertions(+), 45 deletions(-) diff --git a/django/contrib/auth/base_user.py b/django/contrib/auth/base_user.py index 34dd6ac2f2..cf3c71d751 100644 --- a/django/contrib/auth/base_user.py +++ b/django/contrib/auth/base_user.py @@ -119,12 +119,6 @@ class AbstractBaseUser(models.Model): def has_usable_password(self): return is_password_usable(self.password) - def get_full_name(self): - raise NotImplementedError('subclasses of AbstractBaseUser must provide a get_full_name() method') - - def get_short_name(self): - raise NotImplementedError('subclasses of AbstractBaseUser must provide a get_short_name() method.') - def get_session_auth_hash(self): """ Return an HMAC of the password field. diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 7b114f2e8a..5afe526d13 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -319,6 +319,13 @@ Miscellaneous an input of ``"1.345"`` is now converted to ``1345`` instead of ``1.345``. +* Subclasses of :class:`~django.contrib.auth.models.AbstractBaseUser` are no + longer required to implement ``get_short_name()`` and ``get_full_name()``. + (The base implementations that raise ``NotImplementedError`` are removed.) + ``django.contrib.admin`` uses these methods if implemented but doesn't + require them. Third-party apps that use these methods may want to adopt a + similar approach. + .. _deprecated-features-2.0: Features deprecated in 2.0 diff --git a/docs/topics/auth/customizing.txt b/docs/topics/auth/customizing.txt index d385e50a57..22ab1d52fe 100644 --- a/docs/topics/auth/customizing.txt +++ b/docs/topics/auth/customizing.txt @@ -536,18 +536,11 @@ Specifying a custom user model Django expects your custom user model to meet some minimum requirements. -#. If you use the default authentication backend, then your model must have a - single unique field that can be used for identification purposes. This can - be a username, an email address, or any other unique attribute. A non-unique - username field is allowed if you use a custom authentication backend that - can support it. - -#. Your model must provide a way to address the user in a "short" and - "long" form. The most common interpretation of this would be to use - the user's given name as the "short" identifier, and the user's full - name as the "long" identifier. However, there are no constraints on - what these two methods return - if you want, they can return exactly - the same value. +If you use the default authentication backend, then your model must have a +single unique field that can be used for identification purposes. This can +be a username, an email address, or any other unique attribute. A non-unique +username field is allowed if you use a custom authentication backend that +can support it. The easiest way to construct a compliant custom user model is to inherit from :class:`~django.contrib.auth.models.AbstractBaseUser`. @@ -636,16 +629,21 @@ password resets. You must then provide some key implementation details: .. method:: get_full_name() - A longer formal identifier for the user. A common interpretation - would be the full name of the user, but it can be any string that - identifies the user. + Optional. A longer formal identifier for the user such as their full + name. If implemented, this appears alongside the username in an + object's history in :mod:`django.contrib.admin`. .. method:: get_short_name() - A short, informal identifier for the user. A common interpretation - would be the first name of the user, but it can be any string that - identifies the user in an informal way. It may also return the same - value as :meth:`django.contrib.auth.models.User.get_full_name()`. + Optional. A short, informal identifier for the user such as their + first name. If implemented, this replaces the username in the greeting + to the user in the header of :mod:`django.contrib.admin`. + + .. versionchanged:: 2.0 + + In older versions, subclasses are required to implement + ``get_short_name()`` and ``get_full_name()`` as ``AbstractBaseUser`` + has implementations that raise ``NotImplementedError``. .. admonition:: Importing ``AbstractBaseUser`` @@ -1060,14 +1058,6 @@ authentication app:: USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['date_of_birth'] - def get_full_name(self): - # The user is identified by their email address - return self.email - - def get_short_name(self): - # The user is identified by their email address - return self.email - def __str__(self): return self.email diff --git a/tests/auth_tests/models/custom_permissions.py b/tests/auth_tests/models/custom_permissions.py index 73c10e5040..bddcfde2eb 100644 --- a/tests/auth_tests/models/custom_permissions.py +++ b/tests/auth_tests/models/custom_permissions.py @@ -27,11 +27,5 @@ with RemoveGroupsAndPermissions(): USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['date_of_birth'] - def get_full_name(self): - return self.email - - def get_short_name(self): - return self.email - def __str__(self): return self.email diff --git a/tests/auth_tests/models/custom_user.py b/tests/auth_tests/models/custom_user.py index 60fcc494c4..ad8b4c1212 100644 --- a/tests/auth_tests/models/custom_user.py +++ b/tests/auth_tests/models/custom_user.py @@ -43,12 +43,6 @@ class CustomUser(AbstractBaseUser): USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['date_of_birth'] - def get_full_name(self): - return self.email - - def get_short_name(self): - return self.email - def __str__(self): return self.email