Loading django/contrib/admin/sites.py +14 −4 Original line number Diff line number Diff line Loading @@ -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): Loading Loading @@ -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) Loading @@ -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, Loading docs/ref/contrib/admin/index.txt +21 −0 Original line number Diff line number Diff line Loading @@ -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 Loading docs/releases/1.9.txt +5 −0 Original line number Diff line number Diff line Loading @@ -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` ^^^^^^^^^^^^^^^^^^^^^^^^^^ Loading tests/admin_views/test_adminsite.py 0 → 100644 +82 −0 Original line number Diff line number Diff line 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') Loading
django/contrib/admin/sites.py +14 −4 Original line number Diff line number Diff line Loading @@ -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): Loading Loading @@ -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) Loading @@ -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, Loading
docs/ref/contrib/admin/index.txt +21 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
docs/releases/1.9.txt +5 −0 Original line number Diff line number Diff line Loading @@ -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` ^^^^^^^^^^^^^^^^^^^^^^^^^^ Loading
tests/admin_views/test_adminsite.py 0 → 100644 +82 −0 Original line number Diff line number Diff line 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')