diff --git a/django/contrib/auth/__init__.py b/django/contrib/auth/__init__.py index 065eaddd590c3..1050d1d1bbfaa 100644 --- a/django/contrib/auth/__init__.py +++ b/django/contrib/auth/__init__.py @@ -101,7 +101,10 @@ def get_user_model(): app_label, model_name = settings.AUTH_USER_MODEL.split('.') except ValueError: raise ImproperlyConfigured("AUTH_USER_MODEL must be of the form 'app_label.model_name'") - return get_model(app_label, model_name) + user_model = get_model(app_label, model_name) + if user_model is None: + raise ImproperlyConfigured("AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL) + return user_model def get_user(request): diff --git a/django/contrib/auth/tests/basic.py b/django/contrib/auth/tests/basic.py index ec8844026c6de..ed1d0674fcf72 100644 --- a/django/contrib/auth/tests/basic.py +++ b/django/contrib/auth/tests/basic.py @@ -1,10 +1,14 @@ import locale +from django.contrib.auth import get_user_model from django.contrib.auth.management.commands import createsuperuser from django.contrib.auth.models import User, AnonymousUser +from django.contrib.auth.tests.custom_user import CustomUser from django.contrib.auth.tests.utils import skipIfCustomUser +from django.core.exceptions import ImproperlyConfigured from django.core.management import call_command from django.test import TestCase +from django.test.utils import override_settings from django.utils.six import StringIO @@ -149,3 +153,24 @@ class mock_getpass: # If we were successful, a user should have been created u = User.objects.get(username="nolocale@somewhere.org") self.assertEqual(u.email, 'nolocale@somewhere.org') + + def test_get_user_model(self): + "The current user model can be retrieved" + self.assertEqual(get_user_model(), User) + + @override_settings(AUTH_USER_MODEL='auth.CustomUser') + def test_swappable_user(self): + "The current user model can be swapped out for another" + self.assertEqual(get_user_model(), CustomUser) + + @override_settings(AUTH_USER_MODEL='badsetting') + def test_swappable_user_bad_setting(self): + "The alternate user setting must point to something in the format app.model" + with self.assertRaises(ImproperlyConfigured): + get_user_model() + + @override_settings(AUTH_USER_MODEL='thismodel.doesntexist') + def test_swappable_user_nonexistent_model(self): + "The current user model must point to an installed model" + with self.assertRaises(ImproperlyConfigured): + get_user_model() diff --git a/docs/topics/auth.txt b/docs/topics/auth.txt index 2eb98e383ba32..1f95358b1fdae 100644 --- a/docs/topics/auth.txt +++ b/docs/topics/auth.txt @@ -1791,7 +1791,7 @@ different User model. Instead of referring to :class:`~django.contrib.auth.models.User` directly, you should reference the user model using -:meth:`~django.contrib.auth.get_user_model()`. This method will return the +:func:`django.contrib.auth.get_user_model()`. This method will return the currently active User model -- the custom User model if one is specified, or :class:`~django.contrib.auth.User` otherwise.