diff --git a/cl/lib/admin.py b/cl/lib/admin.py index 754bce6f08..73f443e4eb 100644 --- a/cl/lib/admin.py +++ b/cl/lib/admin.py @@ -1,4 +1,7 @@ +from urllib.parse import urlencode + from django.contrib.contenttypes.admin import GenericTabularInline +from django.urls import reverse from cl.lib.models import Note @@ -13,3 +16,28 @@ class Media: class NotesInline(GenericTabularInline): model = Note extra = 1 + + +def build_admin_url(model_class, query_params=None, view_name="changelist"): + """ + Construct a URL for a given model's admin view, optionally appending query parameters. + + :param model_class: The Django model class for which the admin URL will be built. + :param query_params: A dictionary of query parameters to append to the URL (e.g. {"docket": 123}). + :param view_name: An admin view suffix, such as "changelist", "change", or "delete". Defaults to "changelist". + :return: A string representing the fully constructed admin URL, including any query parameters. + + Example usage: + >>> from cl.search.models import DocketEntry + >>> build_admin_url(DocketEntry, {"docket": "1234"}) + '/admin/search/docketentry/?docket=1234' + """ + query_params = query_params or {} + app_label = model_class._meta.app_label + model_name = model_class._meta.model_name + # "admin:app_label_modelname_changelist" is the standard naming for admin changelist + entries_changelist_url = reverse( + f"admin:{app_label}_{model_name}_{view_name}" + ) + query_params = urlencode(query_params) + return f"{entries_changelist_url}?{query_params}" diff --git a/cl/search/admin.py b/cl/search/admin.py index ad8a7270ed..45344c67d2 100644 --- a/cl/search/admin.py +++ b/cl/search/admin.py @@ -3,8 +3,8 @@ from django.db.models import QuerySet from django.http import HttpRequest -from cl.alerts.admin import DocketAlertInline from cl.alerts.models import DocketAlert +from cl.lib.admin import build_admin_url from cl.lib.cloud_front import invalidate_cloudfront from cl.lib.models import THUMBNAIL_STATUSES from cl.lib.string_utils import trunc @@ -300,20 +300,19 @@ def change_view(self, request, object_id, form_url="", extra_context=None): """Add links to pre-filtered related admin pages.""" extra_context = extra_context or {} docket = self.get_object(request, object_id) + query_params = {"docket": object_id} if docket and hasattr(docket, "docket_entries"): - docket_entries_url = ( - f"/admin/{DocketEntry._meta.app_label}/" - f"{DocketEntry._meta.model_name}/?docket={object_id}" + extra_context["docket_entries_url"] = build_admin_url( + DocketEntry, + query_params, ) - extra_context["docket_entries_url"] = docket_entries_url if docket and hasattr(docket, "alerts"): - docket_alerts_url = ( - f"/admin/{DocketAlert._meta.app_label}/" - f"{DocketAlert._meta.model_name}/?docket={object_id}" + extra_context["docket_alerts_url"] = build_admin_url( + DocketAlert, + query_params, ) - extra_context["docket_alerts_url"] = docket_alerts_url return super().change_view( request, object_id, form_url, extra_context=extra_context diff --git a/cl/users/admin.py b/cl/users/admin.py index 0a29c9f074..d501b392bb 100644 --- a/cl/users/admin.py +++ b/cl/users/admin.py @@ -12,7 +12,7 @@ NeonMembershipInline, ) from cl.favorites.admin import NoteInline, UserTagInline -from cl.lib.admin import AdminTweaksMixin +from cl.lib.admin import AdminTweaksMixin, build_admin_url from cl.users.models import ( BarMembership, EmailFlag, @@ -93,19 +93,18 @@ def change_view(self, request, object_id, form_url="", extra_context=None): """Add links to related event admin pages filtered by user/profile.""" extra_context = extra_context or {} user = self.get_object(request, object_id) - proxy_events_url = ( - f"/admin/{UserProxyEvent._meta.app_label}/" - f"{UserProxyEvent._meta.model_name}/?pgh_obj={object_id}" + + extra_context["proxy_events_url"] = build_admin_url( + UserProxyEvent, + {"pgh_obj": object_id}, ) - extra_context["proxy_events_url"] = proxy_events_url if user and hasattr(user, "profile"): profile_id = user.profile.pk - profile_events_url = ( - f"/admin/{UserProfileEvent._meta.app_label}/" - f"{UserProfileEvent._meta.model_name}/?pgh_obj={profile_id}" + extra_context["profile_events_url"] = build_admin_url( + UserProfileEvent, + {"pgh_obj": profile_id}, ) - extra_context["profile_events_url"] = profile_events_url return super().change_view( request, object_id, form_url, extra_context=extra_context