mirror of
https://github.com/django/django.git
synced 2024-12-22 17:16:24 +00:00
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 Tobin <rmtobin@me.com>
|
||||||
Rachel Willmer <http://www.willmer.com/kb/>
|
Rachel Willmer <http://www.willmer.com/kb/>
|
||||||
Radek Švarz <http://www.svarz.cz/translate/>
|
Radek Švarz <http://www.svarz.cz/translate/>
|
||||||
|
Raffaele Salmaso <raffaele@salmaso.org>
|
||||||
Rajesh Dhawan <rajesh.dhawan@gmail.com>
|
Rajesh Dhawan <rajesh.dhawan@gmail.com>
|
||||||
Ramez Ashraf <ramezashraf@gmail.com>
|
Ramez Ashraf <ramezashraf@gmail.com>
|
||||||
Ramin Farajpour Cami <ramin.blackhat@gmail.com>
|
Ramin Farajpour Cami <ramin.blackhat@gmail.com>
|
||||||
|
@ -7,6 +7,7 @@ from django.utils.translation import gettext_lazy as _
|
|||||||
class SimpleAdminConfig(AppConfig):
|
class SimpleAdminConfig(AppConfig):
|
||||||
"""Simple AppConfig which does not do automatic discovery."""
|
"""Simple AppConfig which does not do automatic discovery."""
|
||||||
|
|
||||||
|
default_site = 'django.contrib.admin.sites.AdminSite'
|
||||||
name = 'django.contrib.admin'
|
name = 'django.contrib.admin'
|
||||||
verbose_name = _("Administration")
|
verbose_name = _("Administration")
|
||||||
|
|
||||||
|
@ -9,6 +9,8 @@ from django.db.models.base import ModelBase
|
|||||||
from django.http import Http404, HttpResponseRedirect
|
from django.http import Http404, HttpResponseRedirect
|
||||||
from django.template.response import TemplateResponse
|
from django.template.response import TemplateResponse
|
||||||
from django.urls import NoReverseMatch, reverse
|
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.text import capfirst
|
||||||
from django.utils.translation import gettext as _, gettext_lazy
|
from django.utils.translation import gettext as _, gettext_lazy
|
||||||
from django.views.decorators.cache import never_cache
|
from django.views.decorators.cache import never_cache
|
||||||
@ -518,6 +520,14 @@ class AdminSite:
|
|||||||
], context)
|
], 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.
|
# 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.
|
# You can provide your own AdminSite using the (Simple)AdminConfig.default_site
|
||||||
site = AdminSite()
|
# 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`,
|
This class works like :class:`~django.contrib.admin.apps.AdminConfig`,
|
||||||
except it doesn't call :func:`~django.contrib.admin.autodiscover()`.
|
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
|
.. function:: autodiscover
|
||||||
|
|
||||||
This function attempts to import an ``admin`` module in each installed
|
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
|
this class is created as ``django.contrib.admin.site`` and you can
|
||||||
register your models and ``ModelAdmin`` instances with it.
|
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
|
When constructing an instance of an ``AdminSite``, you can provide
|
||||||
a unique instance name using the ``name`` argument to the constructor. This
|
a unique instance name using the ``name`` argument to the constructor. This
|
||||||
instance name is used to identify the instance, especially when
|
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
|
put ``'django.contrib.admin.apps.SimpleAdminConfig'`` instead of
|
||||||
``'django.contrib.admin'`` in your :setting:`INSTALLED_APPS` setting.
|
``'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:
|
||||||
|
|
||||||
Multiple admin sites in the same URLconf
|
Multiple admin sites in the same URLconf
|
||||||
|
@ -40,6 +40,9 @@ Minor features
|
|||||||
* The new :meth:`.ModelAdmin.delete_queryset` method allows customizing the
|
* The new :meth:`.ModelAdmin.delete_queryset` method allows customizing the
|
||||||
deletion process of the "delete selected objects" action.
|
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`
|
:mod:`django.contrib.admindocs`
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
0
tests/admin_default_site/__init__.py
Normal file
0
tests/admin_default_site/__init__.py
Normal file
6
tests/admin_default_site/apps.py
Normal file
6
tests/admin_default_site/apps.py
Normal file
@ -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'
|
5
tests/admin_default_site/sites.py
Normal file
5
tests/admin_default_site/sites.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
|
||||||
|
class CustomAdminSite(admin.AdminSite):
|
||||||
|
pass
|
31
tests/admin_default_site/tests.py
Normal file
31
tests/admin_default_site/tests.py
Normal file
@ -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
Block a user