summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Dufresne <jon.dufresne@gmail.com>2016-09-10 16:38:05 -0700
committerGitHub <noreply@github.com>2016-09-10 16:38:05 -0700
commit1ec1633cb294d8ce2a65ece6b56c258483596fba (patch)
tree49e7163dad4220da3d99be0a5d981a1a735570a3
parent0368d63a78b07e794138a65216b91eadbb47fc2f (diff)
downloaddjango-1ec1633cb294d8ce2a65ece6b56c258483596fba.tar.gz
Fixed #26401 -- Added BaseAuthConfig to use auth without migrations.
-rw-r--r--django/contrib/auth/apps.py16
-rw-r--r--docs/ref/contrib/auth.txt17
-rw-r--r--docs/releases/1.11.txt4
-rw-r--r--docs/topics/auth/customizing.txt25
-rw-r--r--tests/auth_tests/test_apps.py61
5 files changed, 121 insertions, 2 deletions
diff --git a/django/contrib/auth/apps.py b/django/contrib/auth/apps.py
index d5590158cf..9d128db39c 100644
--- a/django/contrib/auth/apps.py
+++ b/django/contrib/auth/apps.py
@@ -7,14 +7,26 @@ from .checks import check_models_permissions, check_user_model
from .management import create_permissions
-class AuthConfig(AppConfig):
+class BaseAuthConfig(AppConfig):
+ """
+ AppConfig which assumes that the auth models don't exist.
+ """
name = 'django.contrib.auth'
verbose_name = _("Authentication and Authorization")
def ready(self):
+ checks.register(check_user_model, checks.Tags.models)
+
+
+class AuthConfig(BaseAuthConfig):
+ """
+ The default AppConfig for auth.
+ """
+
+ def ready(self):
+ super(AuthConfig, self).ready()
post_migrate.connect(
create_permissions,
dispatch_uid="django.contrib.auth.management.create_permissions"
)
- checks.register(check_user_model, checks.Tags.models)
checks.register(check_models_permissions, checks.Tags.models)
diff --git a/docs/ref/contrib/auth.txt b/docs/ref/contrib/auth.txt
index 91e3fbd1ba..f12b16daa0 100644
--- a/docs/ref/contrib/auth.txt
+++ b/docs/ref/contrib/auth.txt
@@ -645,3 +645,20 @@ The following backends are available in :mod:`django.contrib.auth.backends`:
Same as :class:`RemoteUserBackend` except that it doesn't reject inactive
users because :attr:`~RemoteUserBackend.user_can_authenticate` always
returns ``True``.
+
+``AppConfig`` classes
+=====================
+
+.. module:: django.contrib.auth.apps
+ :synopsis: AppConfigs for contrib.auth.
+
+.. class:: AuthConfig
+
+ The default :class:`~django.apps.AppConfig`.
+
+.. class:: BaseAuthConfig
+
+ .. versionadded:: 1.11
+
+ An :class:`~django.apps.AppConfig` for use if you :ref:`aren't using
+ <using-auth-without-models>` any of the built-in ``contrib.auth`` models.
diff --git a/docs/releases/1.11.txt b/docs/releases/1.11.txt
index 49540a320a..b2ba159c8a 100644
--- a/docs/releases/1.11.txt
+++ b/docs/releases/1.11.txt
@@ -109,6 +109,10 @@ Minor features
* Added password validators ``help_text`` to
:class:`~django.contrib.auth.forms.UserCreationForm`.
+* The new :class:`~django.contrib.auth.apps.BaseAuthConfig` ``AppConfig``
+ allows using the authentication system :ref:`without any of the built-in
+ models <using-auth-without-models>`.
+
:mod:`django.contrib.contenttypes`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/topics/auth/customizing.txt b/docs/topics/auth/customizing.txt
index db18bfb8c2..d102d9939b 100644
--- a/docs/topics/auth/customizing.txt
+++ b/docs/topics/auth/customizing.txt
@@ -1133,3 +1133,28 @@ Finally, specify the custom model as the default user model for your project
using the :setting:`AUTH_USER_MODEL` setting in your ``settings.py``::
AUTH_USER_MODEL = 'customauth.MyUser'
+
+.. _using-auth-without-models:
+
+Using ``contrib.auth`` without the built-in models
+==================================================
+
+The models shipped with ``contrib.auth`` may not be required. For example, if
+you :ref:`customize the user model <auth-custom-user>` and don't use the
+:class:`~django.contrib.auth.models.Permission` and
+:class:`~django.contrib.auth.models.Group` models, then the ``auth`` tables
+may be unused. To avoid creating these tables, modify the
+:setting:`MIGRATION_MODULES` setting and disable the migrations for the
+``auth`` app::
+
+ MIGRATION_MODULES = {'auth': None}
+
+To prevent creation of the default permissions, change ``'django.contrib.auth'``
+in :setting:`INSTALLED_APPS` to
+:class:`django.contrib.auth.apps.BaseAuthConfig`::
+
+ INSTALLED_APPS = [
+ ...
+ 'django.contrib.auth.apps.BaseAuthConfig',
+ ...
+ ]
diff --git a/tests/auth_tests/test_apps.py b/tests/auth_tests/test_apps.py
new file mode 100644
index 0000000000..e1c386c95e
--- /dev/null
+++ b/tests/auth_tests/test_apps.py
@@ -0,0 +1,61 @@
+import os
+import shutil
+import subprocess
+import sys
+import tempfile
+import unittest
+
+from django.db import ConnectionHandler
+
+SETTINGS = """
+SECRET_KEY = 'django_auth_tests_secret_key'
+
+INSTALLED_APPS = [
+ 'django.contrib.auth.apps.BaseAuthConfig',
+ 'django.contrib.contenttypes',
+]
+
+MIGRATION_MODULES = {'auth': None}
+
+DATABASES = %(databases)r
+"""
+
+
+class AppConfigTests(unittest.TestCase):
+ def test_no_migrations(self):
+ project_path = tempfile.mkdtemp()
+ try:
+ databases = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': os.path.join(project_path, 'db.sqlite3'),
+ }
+ }
+
+ with open(os.path.join(project_path, 'no_migrations.py'), 'w') as fp:
+ fp.write(SETTINGS % {'databases': databases})
+
+ with open(os.devnull, 'wb') as devnull:
+ cmd = [
+ sys.executable,
+ '-m', 'django',
+ 'migrate',
+ '--settings', 'no_migrations',
+ '--pythonpath', project_path,
+ ]
+ returncode = subprocess.call(cmd, stdout=devnull, stderr=devnull)
+
+ # Migrate command ran without errors.
+ self.assertEqual(returncode, 0)
+
+ # Auth tables weren't created.
+ conns = ConnectionHandler(databases)
+ try:
+ self.assertEqual(
+ set(conns['default'].introspection.table_names()),
+ {'django_content_type', 'django_migrations'},
+ )
+ finally:
+ conns.close_all()
+ finally:
+ shutil.rmtree(project_path)