mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-14 09:51:22 -06:00
Fixes #12742: Object counts dashboard widget should support URL-compatible query filters
This commit is contained in:
parent
b3bd03a1e9
commit
9b8ab1c1f7
@ -16,6 +16,7 @@
|
|||||||
* [#12627](https://github.com/netbox-community/netbox/issues/12627) - Restore hover preview for embedded image attachment tables
|
* [#12627](https://github.com/netbox-community/netbox/issues/12627) - Restore hover preview for embedded image attachment tables
|
||||||
* [#12694](https://github.com/netbox-community/netbox/issues/12694) - Strip leading & trailing whitespace from custom link URL & text
|
* [#12694](https://github.com/netbox-community/netbox/issues/12694) - Strip leading & trailing whitespace from custom link URL & text
|
||||||
* [#12715](https://github.com/netbox-community/netbox/issues/12715) - Use contact assignments table to display the contacts assigned to an object
|
* [#12715](https://github.com/netbox-community/netbox/issues/12715) - Use contact assignments table to display the contacts assigned to an object
|
||||||
|
* [#12742](https://github.com/netbox-community/netbox/issues/12742) - Object counts dashboard widget should support URL-compatible query filters
|
||||||
* [#12745](https://github.com/netbox-community/netbox/issues/12745) - Escape display text in API-backed selection widgets
|
* [#12745](https://github.com/netbox-community/netbox/issues/12745) - Escape display text in API-backed selection widgets
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -10,8 +10,9 @@ from django.conf import settings
|
|||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
from django.http import QueryDict
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.urls import NoReverseMatch, reverse
|
from django.urls import NoReverseMatch, resolve, reverse
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from extras.utils import FeatureQuery
|
from extras.utils import FeatureQuery
|
||||||
@ -149,7 +150,7 @@ class ObjectCountsWidget(DashboardWidget):
|
|||||||
filters = forms.JSONField(
|
filters = forms.JSONField(
|
||||||
required=False,
|
required=False,
|
||||||
label='Object filters',
|
label='Object filters',
|
||||||
help_text=_("Only objects matching the specified filters will be counted")
|
help_text=_("Filters to apply when counting the number of objects")
|
||||||
)
|
)
|
||||||
|
|
||||||
def clean_filters(self):
|
def clean_filters(self):
|
||||||
@ -158,13 +159,6 @@ class ObjectCountsWidget(DashboardWidget):
|
|||||||
dict(data)
|
dict(data)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
raise forms.ValidationError("Invalid format. Object filters must be passed as a dictionary.")
|
raise forms.ValidationError("Invalid format. Object filters must be passed as a dictionary.")
|
||||||
for model in get_models_from_content_types(self.cleaned_data.get('models')):
|
|
||||||
try:
|
|
||||||
# Validate the filters by creating a QuerySet
|
|
||||||
model.objects.filter(**data).none()
|
|
||||||
except Exception:
|
|
||||||
model_name = model._meta.verbose_name_plural
|
|
||||||
raise forms.ValidationError(f"Invalid filter specification for {model_name}.")
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def render(self, request):
|
def render(self, request):
|
||||||
@ -172,9 +166,14 @@ class ObjectCountsWidget(DashboardWidget):
|
|||||||
for model in get_models_from_content_types(self.config['models']):
|
for model in get_models_from_content_types(self.config['models']):
|
||||||
permission = get_permission_for_model(model, 'view')
|
permission = get_permission_for_model(model, 'view')
|
||||||
if request.user.has_perm(permission):
|
if request.user.has_perm(permission):
|
||||||
|
url = reverse(get_viewname(model, 'list'))
|
||||||
qs = model.objects.restrict(request.user, 'view')
|
qs = model.objects.restrict(request.user, 'view')
|
||||||
|
# Apply any specified filters
|
||||||
if filters := self.config.get('filters'):
|
if filters := self.config.get('filters'):
|
||||||
qs = qs.filter(**filters)
|
params = QueryDict(mutable=True)
|
||||||
|
params.update(filters)
|
||||||
|
filterset = getattr(resolve(url).func.view_class, 'filterset', None)
|
||||||
|
qs = filterset(params, qs).qs
|
||||||
object_count = qs.count
|
object_count = qs.count
|
||||||
counts.append((model, object_count))
|
counts.append((model, object_count))
|
||||||
else:
|
else:
|
||||||
|
Loading…
Reference in New Issue
Block a user