20048 cleanup get_viewname URL resolution (#20050)
CI / build (20.x, 3.10) (push) Waiting to run
CI / build (20.x, 3.11) (push) Waiting to run
CI / build (20.x, 3.12) (push) Waiting to run

* #20048 add get_action_url utility function

* #20048 add get_action_url utility function

* #20048 add get_action_url utility function

* #20048 add get_action_url utility function

* #20048 add get_action_url utility function

* #20048 action_url template tag

* #20048 action_url template tag

* #20048 fix test

* #20048 review feedback

* #20048 fix tags
This commit is contained in:
Arthur Hanson
2025-08-11 05:38:19 -07:00
committed by GitHub
parent 1242ad68f7
commit a585bc044e
24 changed files with 220 additions and 115 deletions
+7 -9
View File
@@ -11,7 +11,7 @@ from django.conf import settings
from django.core.cache import cache
from django.db.models import Model
from django.template.loader import render_to_string
from django.urls import NoReverseMatch, resolve, reverse
from django.urls import NoReverseMatch, resolve
from django.utils.translation import gettext as _
from core.models import ObjectType
@@ -21,7 +21,7 @@ from utilities.permissions import get_permission_for_model
from utilities.proxy import resolve_proxies
from utilities.querydict import dict_to_querydict
from utilities.templatetags.builtins.filters import render_markdown
from utilities.views import get_viewname
from utilities.views import get_action_url
from .utils import register_widget
__all__ = (
@@ -53,9 +53,9 @@ def object_list_widget_supports_model(model: Model) -> bool:
"""
def can_resolve_model_list_view(model: Model) -> bool:
try:
reverse(get_viewname(model, action='list'))
get_action_url(model, action='list')
return True
except Exception:
except NoReverseMatch:
return False
tests = [
@@ -206,7 +206,7 @@ class ObjectCountsWidget(DashboardWidget):
permission = get_permission_for_model(model, 'view')
if request.user.has_perm(permission):
try:
url = reverse(get_viewname(model, 'list'))
url = get_action_url(model, action='list')
except NoReverseMatch:
url = None
qs = model.objects.restrict(request.user, 'view')
@@ -275,15 +275,13 @@ class ObjectListWidget(DashboardWidget):
logger.debug(f"Dashboard Widget model_class not found: {app_label}:{model_name}")
return
viewname = get_viewname(model, action='list')
# Evaluate user's permission. Note that this controls only whether the HTMX element is
# embedded on the page: The view itself will also evaluate permissions separately.
permission = get_permission_for_model(model, 'view')
has_permission = request.user.has_perm(permission)
try:
htmx_url = reverse(viewname)
htmx_url = get_action_url(model, action='list')
except NoReverseMatch:
htmx_url = None
parameters = self.config.get('url_params') or {}
@@ -297,7 +295,7 @@ class ObjectListWidget(DashboardWidget):
except ValueError:
pass
return render_to_string(self.template_name, {
'viewname': viewname,
'model_name': model_name,
'has_permission': has_permission,
'htmx_url': htmx_url,
})
+1 -1
View File
@@ -45,4 +45,4 @@ class ObjectListWidgetTests(TestCase):
mock_request = Request()
widget = ObjectListWidget(id='2829fd9b-5dee-4c9a-81f2-5bd84c350a27', **config)
rendered = widget.render(mock_request)
self.assertTrue('Unable to load content. Invalid view name:' in rendered)
self.assertTrue('Unable to load content. Could not resolve list URL for:' in rendered)
+3 -5
View File
@@ -31,7 +31,7 @@ from utilities.querydict import normalize_querydict
from utilities.request import copy_safe_request
from utilities.rqworker import get_workers_for_queue
from utilities.templatetags.builtins.filters import render_markdown
from utilities.views import ContentTypePermissionRequiredMixin, get_viewname, register_model_view
from utilities.views import ContentTypePermissionRequiredMixin, get_action_url, register_model_view
from virtualization.models import VirtualMachine
from . import filtersets, forms, tables
from .constants import LOG_LEVEL_RANK
@@ -1103,8 +1103,7 @@ class JournalEntryEditView(generic.ObjectEditView):
if not instance.assigned_object:
return reverse('extras:journalentry_list')
obj = instance.assigned_object
viewname = get_viewname(obj, 'journal')
return reverse(viewname, kwargs={'pk': obj.pk})
return get_action_url(obj, action='journal', kwargs={'pk': obj.pk})
@register_model_view(JournalEntry, 'delete')
@@ -1113,8 +1112,7 @@ class JournalEntryDeleteView(generic.ObjectDeleteView):
def get_return_url(self, request, instance):
obj = instance.assigned_object
viewname = get_viewname(obj, 'journal')
return reverse(viewname, kwargs={'pk': obj.pk})
return get_action_url(obj, action='journal', kwargs={'pk': obj.pk})
@register_model_view(JournalEntry, 'bulk_import', path='import', detail=False)