Fixed #26401 -- Added BaseAuthConfig to use auth without migrations.

This commit is contained in:
Jon Dufresne 2016-09-10 16:38:05 -07:00 committed by GitHub
parent 0368d63a78
commit 1ec1633cb2
5 changed files with 121 additions and 2 deletions

View File

@ -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)

View File

@ -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.

View File

@ -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`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -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',
...
]

View File

@ -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)