Fixed #8500 -- Allowed overriding the default admin site instance.
This commit is contained in:
parent
d0a42a14c0
commit
da3df5b878
1
AUTHORS
1
AUTHORS
|
@ -666,6 +666,7 @@ answer newbie questions, and generally made Django that much better:
|
|||
Rachel Tobin <rmtobin@me.com>
|
||||
Rachel Willmer <http://www.willmer.com/kb/>
|
||||
Radek Švarz <http://www.svarz.cz/translate/>
|
||||
Raffaele Salmaso <raffaele@salmaso.org>
|
||||
Rajesh Dhawan <rajesh.dhawan@gmail.com>
|
||||
Ramez Ashraf <ramezashraf@gmail.com>
|
||||
Ramin Farajpour Cami <ramin.blackhat@gmail.com>
|
||||
|
|
|
@ -7,6 +7,7 @@ from django.utils.translation import gettext_lazy as _
|
|||
class SimpleAdminConfig(AppConfig):
|
||||
"""Simple AppConfig which does not do automatic discovery."""
|
||||
|
||||
default_site = 'django.contrib.admin.sites.AdminSite'
|
||||
name = 'django.contrib.admin'
|
||||
verbose_name = _("Administration")
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@ from django.db.models.base import ModelBase
|
|||
from django.http import Http404, HttpResponseRedirect
|
||||
from django.template.response import TemplateResponse
|
||||
from django.urls import NoReverseMatch, reverse
|
||||
from django.utils.functional import LazyObject
|
||||
from django.utils.module_loading import import_string
|
||||
from django.utils.text import capfirst
|
||||
from django.utils.translation import gettext as _, gettext_lazy
|
||||
from django.views.decorators.cache import never_cache
|
||||
|
@ -518,6 +520,14 @@ class AdminSite:
|
|||
], context)
|
||||
|
||||
|
||||
class DefaultAdminSite(LazyObject):
|
||||
def _setup(self):
|
||||
AdminSiteClass = import_string(apps.get_app_config('admin').default_site)
|
||||
self._wrapped = AdminSiteClass()
|
||||
|
||||
|
||||
# This global object represents the default admin site, for the common case.
|
||||
# You can instantiate AdminSite in your own code to create a custom admin site.
|
||||
site = AdminSite()
|
||||
# You can provide your own AdminSite using the (Simple)AdminConfig.default_site
|
||||
# attribute. You can also instantiate AdminSite in your own code to create a
|
||||
# custom admin site.
|
||||
site = DefaultAdminSite()
|
||||
|
|
|
@ -157,6 +157,15 @@ application and imports it.
|
|||
This class works like :class:`~django.contrib.admin.apps.AdminConfig`,
|
||||
except it doesn't call :func:`~django.contrib.admin.autodiscover()`.
|
||||
|
||||
.. attribute:: default_site
|
||||
|
||||
.. versionadded:: 2.1
|
||||
|
||||
A dotted import path to the default admin site's class or to a callable
|
||||
that returns a site instance. Defaults to
|
||||
``'django.contrib.admin.sites.AdminSite'``. See
|
||||
:ref:`overriding-default-admin-site` for usage.
|
||||
|
||||
.. function:: autodiscover
|
||||
|
||||
This function attempts to import an ``admin`` module in each installed
|
||||
|
@ -2627,6 +2636,9 @@ creating your own ``AdminSite`` instance (see below), and changing the
|
|||
this class is created as ``django.contrib.admin.site`` and you can
|
||||
register your models and ``ModelAdmin`` instances with it.
|
||||
|
||||
If you want to customize the default admin site, you can :ref:`override it
|
||||
<overriding-default-admin-site>`.
|
||||
|
||||
When constructing an instance of an ``AdminSite``, you can provide
|
||||
a unique instance name using the ``name`` argument to the constructor. This
|
||||
instance name is used to identify the instance, especially when
|
||||
|
@ -2819,6 +2831,43 @@ own ``AdminSite`` instance since you will likely be importing all the per-app
|
|||
put ``'django.contrib.admin.apps.SimpleAdminConfig'`` instead of
|
||||
``'django.contrib.admin'`` in your :setting:`INSTALLED_APPS` setting.
|
||||
|
||||
.. _overriding-default-admin-site:
|
||||
|
||||
Overriding the default admin site
|
||||
---------------------------------
|
||||
|
||||
.. versionadded:: 2.1
|
||||
|
||||
You can override the default ``django.contrib.admin.site`` by setting the
|
||||
:attr:`~.SimpleAdminConfig.default_site` attribute of a custom ``AppConfig``
|
||||
to the dotted import path of either a ``AdminSite`` subclass or a callable that
|
||||
returns a site instance.
|
||||
|
||||
.. snippet::
|
||||
:filename: myproject/admin.py
|
||||
|
||||
from django.contrib import admin
|
||||
|
||||
class MyAdminSite(admin.AdminSite):
|
||||
...
|
||||
|
||||
.. snippet::
|
||||
:filename: myproject/apps.py
|
||||
|
||||
from django.contrib.admin.apps import AdminConfig
|
||||
|
||||
class MyAdminConfig(AdminConfig):
|
||||
default_site = 'myproject.admin.MyAdminSite'
|
||||
|
||||
.. snippet::
|
||||
:filename: myproject/settings.py
|
||||
|
||||
INSTALLED_APPS = [
|
||||
...
|
||||
'myproject.apps.MyAdminConfig', # replaces 'django.contrib.admin'
|
||||
...
|
||||
]
|
||||
|
||||
.. _multiple-admin-sites:
|
||||
|
||||
Multiple admin sites in the same URLconf
|
||||
|
|
|
@ -40,6 +40,9 @@ Minor features
|
|||
* The new :meth:`.ModelAdmin.delete_queryset` method allows customizing the
|
||||
deletion process of the "delete selected objects" action.
|
||||
|
||||
* You can now :ref:`override the the default admin site
|
||||
<overriding-default-admin-site>`.
|
||||
|
||||
:mod:`django.contrib.admindocs`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
from django.contrib.admin.apps import SimpleAdminConfig
|
||||
|
||||
|
||||
class MyCustomAdminConfig(SimpleAdminConfig):
|
||||
verbose_name = 'My custom default admin site.'
|
||||
default_site = 'admin_default_site.sites.CustomAdminSite'
|
|
@ -0,0 +1,5 @@
|
|||
from django.contrib import admin
|
||||
|
||||
|
||||
class CustomAdminSite(admin.AdminSite):
|
||||
pass
|
|
@ -0,0 +1,31 @@
|
|||
from django.contrib import admin
|
||||
from django.contrib.admin import sites
|
||||
from django.test import SimpleTestCase, override_settings
|
||||
|
||||
|
||||
@override_settings(INSTALLED_APPS=[
|
||||
'admin_default_site.apps.MyCustomAdminConfig',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
])
|
||||
class CustomAdminSiteTests(SimpleTestCase):
|
||||
|
||||
def setUp(self):
|
||||
# Reset admin.site since it may have already been instantiated by
|
||||
# another test app.
|
||||
self._old_site = admin.site
|
||||
admin.site = sites.site = sites.DefaultAdminSite()
|
||||
|
||||
def tearDown(self):
|
||||
admin.site = sites.site = self._old_site
|
||||
|
||||
def test_use_custom_admin_site(self):
|
||||
self.assertEqual(admin.site.__class__.__name__, 'CustomAdminSite')
|
||||
|
||||
|
||||
class DefaultAdminSiteTests(SimpleTestCase):
|
||||
def test_use_default_admin_site(self):
|
||||
self.assertEqual(admin.site.__class__.__name__, 'AdminSite')
|
Loading…
Reference in New Issue