summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRiccardo Magliocchetti <riccardo.magliocchetti@gmail.com>2015-03-30 12:54:25 +0200
committerTim Graham <timograham@gmail.com>2015-05-11 12:07:36 -0400
commitbd53db5eab05099ae371348529c6428e0da95c6a (patch)
tree3920514c719a6cacc2ba6a8dc7c6d441735bde30
parentadc57632bc26cc8fe42bdb6aff463f883214980a (diff)
Fixed #24553 -- Added the list of available applications to AdminSite.each_context()
-rw-r--r--django/contrib/admin/sites.py18
-rw-r--r--docs/ref/contrib/admin/index.txt21
-rw-r--r--docs/releases/1.9.txt5
-rw-r--r--tests/admin_views/test_adminsite.py82
4 files changed, 122 insertions, 4 deletions
diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py
index cec3f5aa67..3dc5075443 100644
--- a/django/contrib/admin/sites.py
+++ b/django/contrib/admin/sites.py
@@ -301,6 +301,7 @@ class AdminSite(object):
'site_header': self.site_header,
'site_url': self.site_url,
'has_permission': self.has_permission(request),
+ 'available_apps': self.get_app_list(request),
}
def password_change(self, request, extra_context=None):
@@ -461,11 +462,10 @@ class AdminSite(object):
return app_dict.get(label)
return app_dict
- @never_cache
- def index(self, request, extra_context=None):
+ def get_app_list(self, request):
"""
- Displays the main admin index page, which lists all of the installed
- apps that have been registered in this site.
+ Returns a sorted list of all the installed apps that have been
+ registered in this site.
"""
app_dict = self._build_app_dict(request)
@@ -476,6 +476,16 @@ class AdminSite(object):
for app in app_list:
app['models'].sort(key=lambda x: x['name'])
+ return app_list
+
+ @never_cache
+ def index(self, request, extra_context=None):
+ """
+ Displays the main admin index page, which lists all of the installed
+ apps that have been registered in this site.
+ """
+ app_list = self.get_app_list(request)
+
context = dict(
self.each_context(request),
title=self.index_title,
diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt
index e620f34905..ce218f06dc 100644
--- a/docs/ref/contrib/admin/index.txt
+++ b/docs/ref/contrib/admin/index.txt
@@ -2507,11 +2507,32 @@ Templates can override or extend base admin templates as described in
* ``site_title``: :attr:`AdminSite.site_title`
* ``site_url``: :attr:`AdminSite.site_url`
* ``has_permission``: :meth:`AdminSite.has_permission`
+ * ``available_apps``: a list of applications from the :doc:`application registry
+ </ref/applications/>` available for the current user. Each entry in the
+ list is a dict representing an application with the following keys:
+
+ * ``app_label``: the application label
+ * ``app_url``: the URL of the application index in the admin
+ * ``has_module_perms``: a boolean indicating if displaying and accessing of
+ the module's index page is permitted for the current user
+ * ``models``: a list of the models available in the application
+
+ Each model is a dict with the following keys:
+
+ * ``object_name``: class name of the model
+ * ``name``: plural name of the model
+ * ``perms``: a ``dict`` tracking ``add``, ``change``, and ``delete`` permissions
+ * ``admin_url``: admin changelist URL for the model
+ * ``add_url``: admin URL to add a new model instance
.. versionchanged:: 1.8
The ``request`` argument and the ``has_permission`` variable were added.
+ .. versionchanged:: 1.9
+
+ The ``available_apps`` variable was added.
+
.. method:: AdminSite.has_permission(request)
Returns ``True`` if the user for the given ``HttpRequest`` has permission
diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt
index 99daac6a8f..8be0e334b8 100644
--- a/docs/releases/1.9.txt
+++ b/docs/releases/1.9.txt
@@ -48,6 +48,11 @@ Minor features
changing the ``select_related()`` values used in the admin's changelist query
based on the request.
+* The ``available_apps`` context variable, which lists the available
+ applications for the current user, has been added to the
+ :meth:`AdminSite.each_context() <django.contrib.admin.AdminSite.each_context>`
+ method.
+
:mod:`django.contrib.auth`
^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/admin_views/test_adminsite.py b/tests/admin_views/test_adminsite.py
new file mode 100644
index 0000000000..6e0fce57d8
--- /dev/null
+++ b/tests/admin_views/test_adminsite.py
@@ -0,0 +1,82 @@
+from __future__ import unicode_literals
+
+import datetime
+
+from django.conf.urls import include, url
+from django.contrib import admin
+from django.contrib.auth.models import User
+from django.core.urlresolvers import reverse
+from django.test import TestCase, override_settings
+from django.test.client import RequestFactory
+
+from .models import Article
+
+site = admin.AdminSite(name="test_adminsite")
+site.register(User)
+site.register(Article)
+
+urlpatterns = [
+ url(r'^test_admin/admin/', include(site.urls)),
+]
+
+
+@override_settings(
+ PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher'],
+ ROOT_URLCONF="admin_views.test_adminsite",
+)
+class SiteEachContextTest(TestCase):
+ """
+ Check each_context contains the documented variables and that available_apps context
+ variable structure is the expected one.
+ """
+ @classmethod
+ def setUpTestData(cls):
+ cls.u1 = User.objects.create(
+ id=100, password='sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158',
+ last_login=datetime.datetime(2007, 5, 30, 13, 20, 10), is_superuser=True, username='super',
+ first_name='Super', last_name='User', email='super@example.com',
+ is_staff=True, is_active=True, date_joined=datetime.datetime(2007, 5, 30, 13, 20, 10),
+ )
+
+ def setUp(self):
+ factory = RequestFactory()
+ request = factory.get(reverse('test_adminsite:index'))
+ request.user = self.u1
+ self.ctx = site.each_context(request)
+
+ def test_each_context(self):
+ ctx = self.ctx
+ self.assertEqual(ctx['site_header'], 'Django administration')
+ self.assertEqual(ctx['site_title'], 'Django site admin')
+ self.assertEqual(ctx['site_url'], '/')
+ self.assertEqual(ctx['has_permission'], True)
+
+ def test_available_apps(self):
+ ctx = self.ctx
+ apps = ctx['available_apps']
+ # we have registered two models from two different apps
+ self.assertEqual(len(apps), 2)
+
+ # admin_views.Article
+ admin_views = apps[0]
+ self.assertEqual(admin_views['app_label'], 'admin_views')
+ self.assertEqual(len(admin_views['models']), 1)
+ self.assertEqual(admin_views['models'][0]['object_name'], 'Article')
+
+ # auth.User
+ auth = apps[1]
+ self.assertEqual(auth['app_label'], 'auth')
+ self.assertEqual(len(auth['models']), 1)
+ user = auth['models'][0]
+ self.assertEqual(user['object_name'], 'User')
+
+ self.assertEqual(auth['app_url'], '/test_admin/admin/auth/')
+ self.assertEqual(auth['has_module_perms'], True)
+
+ self.assertIn('perms', user)
+ self.assertEqual(user['perms']['add'], True)
+ self.assertEqual(user['perms']['change'], True)
+ self.assertEqual(user['perms']['delete'], True)
+ self.assertEqual(user['admin_url'], '/test_admin/admin/auth/user/')
+ self.assertEqual(user['add_url'], '/test_admin/admin/auth/user/add/')
+ self.assertEqual(user['name'], 'Users')