summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoradontz <adontz@gmail.com>2022-03-05 20:09:42 +0400
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-03-25 10:33:44 +0100
commit2bee0b4328319eaf6a0d1686677d629f2ecf6dec (patch)
tree116b7dea4223da88dc24b422a08bb9bad8d7d05f
parentd44951b36ef2e698f32a8e1352671689e44c4d62 (diff)
Fixed #7497 -- Allowed overriding the order of apps and models in admin.
-rw-r--r--django/contrib/admin/sites.py18
-rw-r--r--docs/ref/contrib/admin/index.txt33
-rw-r--r--docs/releases/4.1.txt3
-rw-r--r--tests/admin_views/customadmin.py8
-rw-r--r--tests/admin_views/tests.py11
5 files changed, 63 insertions, 10 deletions
diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py
index c8870924e7..47a25608fe 100644
--- a/django/contrib/admin/sites.py
+++ b/django/contrib/admin/sites.py
@@ -526,16 +526,14 @@ class AdminSite:
"models": [model_dict],
}
- if label:
- return app_dict.get(label)
return app_dict
- def get_app_list(self, request):
+ def get_app_list(self, request, app_label=None):
"""
Return a sorted list of all the installed apps that have been
registered in this site.
"""
- app_dict = self._build_app_dict(request)
+ app_dict = self._build_app_dict(request, app_label)
# Sort the apps alphabetically.
app_list = sorted(app_dict.values(), key=lambda x: x["name"].lower())
@@ -568,16 +566,16 @@ class AdminSite:
)
def app_index(self, request, app_label, extra_context=None):
- app_dict = self._build_app_dict(request, app_label)
- if not app_dict:
+ app_list = self.get_app_list(request, app_label)
+
+ if not app_list:
raise Http404("The requested admin page does not exist.")
- # Sort the models alphabetically within each app.
- app_dict["models"].sort(key=lambda x: x["name"])
+
context = {
**self.each_context(request),
- "title": _("%(app)s administration") % {"app": app_dict["name"]},
+ "title": _("%(app)s administration") % {"app": app_list[0]["name"]},
"subtitle": None,
- "app_list": [app_dict],
+ "app_list": app_list,
"app_label": app_label,
**(extra_context or {}),
}
diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt
index ab8da5a729..199a864566 100644
--- a/docs/ref/contrib/admin/index.txt
+++ b/docs/ref/contrib/admin/index.txt
@@ -2896,6 +2896,39 @@ Templates can override or extend base admin templates as described in
The ``model`` variable for each model was added.
+.. method:: AdminSite.get_app_list(request, app_label=None)
+
+ Returns a list of applications from the :doc:`application registry
+ </ref/applications/>` available for the current user. You can optionally
+ pass an ``app_label`` argument to get details for a single app. Each entry
+ in the list is a dictionary 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
+ * ``name``: name of the application
+
+ Each model is a dictionary with the following keys:
+
+ * ``model``: the model class
+ * ``object_name``: class name of the model
+ * ``name``: plural name of the model
+ * ``perms``: a ``dict`` tracking ``add``, ``change``, ``delete``, and
+ ``view`` permissions
+ * ``admin_url``: admin changelist URL for the model
+ * ``add_url``: admin URL to add a new model instance
+
+ Lists of applications and models are sorted alphabetically by their names.
+ You can override this method to change the default order on the admin index
+ page.
+
+ .. versionchanged:: 4.1
+
+ The ``app_label`` argument was added.
+
.. method:: AdminSite.has_permission(request)
Returns ``True`` if the user for the given ``HttpRequest`` has permission
diff --git a/docs/releases/4.1.txt b/docs/releases/4.1.txt
index 885c9329c5..39dd2faba9 100644
--- a/docs/releases/4.1.txt
+++ b/docs/releases/4.1.txt
@@ -63,6 +63,9 @@ Minor features
* Related widget wrappers now have a link to object's change form.
+* The :meth:`.AdminSite.get_app_list` method now allows changing the order of
+ apps and models on the admin index page.
+
:mod:`django.contrib.admindocs`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/tests/admin_views/customadmin.py b/tests/admin_views/customadmin.py
index f9e1f6fe1a..e3429ec4bc 100644
--- a/tests/admin_views/customadmin.py
+++ b/tests/admin_views/customadmin.py
@@ -35,6 +35,14 @@ class Admin2(admin.AdminSite):
def password_change(self, request, extra_context=None):
return super().password_change(request, {"spam": "eggs"})
+ def get_app_list(self, request, app_label=None):
+ app_list = super().get_app_list(request, app_label=app_label)
+ # Reverse order of apps and models.
+ app_list = list(reversed(app_list))
+ for app in app_list:
+ app["models"].sort(key=lambda x: x["name"], reverse=True)
+ return app_list
+
class UserLimitedAdmin(UserAdmin):
# used for testing password change on a user not in queryset
diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py
index acad97923a..185c1bff26 100644
--- a/tests/admin_views/tests.py
+++ b/tests/admin_views/tests.py
@@ -1358,6 +1358,17 @@ class AdminViewBasicTest(AdminViewBasicTestCase):
models = [model["name"] for model in response.context["app_list"][0]["models"]]
self.assertSequenceEqual(models, sorted(models))
+ def test_app_index_context_reordered(self):
+ self.client.force_login(self.superuser)
+ response = self.client.get(reverse("admin2:app_list", args=("admin_views",)))
+ self.assertContains(
+ response,
+ "<title>Admin_Views administration | Django site admin</title>",
+ )
+ # Models are in reverse order.
+ models = [model["name"] for model in response.context["app_list"][0]["models"]]
+ self.assertSequenceEqual(models, sorted(models, reverse=True))
+
def test_change_view_subtitle_per_object(self):
response = self.client.get(
reverse("admin:admin_views_article_change", args=(self.a1.pk,)),