From ecfd36ec3068bf9f4739f3b9050c94bd954114ce Mon Sep 17 00:00:00 2001 From: sarankumar1325 <120080287+sarankumar1325@users.noreply.github.com> Date: Sat, 31 Oct 2026 13:48:06 +0000 Subject: [PATCH] Pass all name[] values to the Django metrics view PrometheusDjangoView passed request.GET straight to _bake_output. QueryDict['name[]'] returns only the last value as a string, so restricted_registry() built a set of its characters and /metrics?name[]=foo returned no metrics. Convert the QueryDict to a dict of lists, matching what parse_qs gives the WSGI app. Signed-off-by: sarankumar1325 <120080287+sarankumar1325@users.noreply.github.com> --- prometheus_client/django/exposition.py | 4 +++- tests/test_django.py | 28 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/prometheus_client/django/exposition.py b/prometheus_client/django/exposition.py index 71fc8d8a..91151911 100644 --- a/prometheus_client/django/exposition.py +++ b/prometheus_client/django/exposition.py @@ -26,7 +26,9 @@ def get(self, request, *args, **kwargs): registry=self.registry, accept_header=accept_header, accept_encoding_header=accept_encoding_header, - params=request.GET, + # QueryDict.__getitem__ returns only the last value, but + # _bake_output expects a list of values per key (like parse_qs). + params=dict(request.GET.lists()), disable_compression=False, ) status = int(status.split(" ")[0]) diff --git a/tests/test_django.py b/tests/test_django.py index 659bb3f6..e02ff568 100644 --- a/tests/test_django.py +++ b/tests/test_django.py @@ -46,3 +46,31 @@ def test_reports_metrics(self): response = PrometheusDjangoView.as_view(registry=self.registry)(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.content, generate_latest(self.registry, ALLOWUTF8)) + + def test_restricted_registry(self): + c = Counter('cc', 'A counter', registry=self.registry) + c.inc() + g = Counter('gg', 'Another counter', registry=self.registry) + g.inc() + + request = self.factory.get("/metrics", {"name[]": ["cc_total"]}) + + response = PrometheusDjangoView.as_view(registry=self.registry)(request) + self.assertEqual(response.status_code, 200) + self.assertEqual( + response.content, + generate_latest(self.registry.restricted_registry(["cc_total"]), ALLOWUTF8), + ) + self.assertNotIn(b"gg_total", response.content) + + def test_restricted_registry_multiple_names(self): + Counter('aa', 'A counter', registry=self.registry).inc() + Counter('bb', 'B counter', registry=self.registry).inc() + Counter('cc', 'C counter', registry=self.registry).inc() + + request = self.factory.get("/metrics", {"name[]": ["aa_total", "bb_total"]}) + + response = PrometheusDjangoView.as_view(registry=self.registry)(request) + self.assertIn(b"aa_total", response.content) + self.assertIn(b"bb_total", response.content) + self.assertNotIn(b"cc_total", response.content)