Browse Source

Fixed #36182 -- Returned "?" if all parameters are removed in querystring template tag.

Thank you to David Feeley for the report and Natalia Bidart for the review.
Sarah Boyce 1 month ago
parent
commit
05002c153c

+ 7 - 7
django/template/defaulttags.py

@@ -1194,18 +1194,18 @@ def querystring(context, query_dict=None, **kwargs):
     """
     if query_dict is None:
         query_dict = context.request.GET
-    query_dict = query_dict.copy()
+    params = query_dict.copy()
     for key, value in kwargs.items():
         if value is None:
-            if key in query_dict:
-                del query_dict[key]
+            if key in params:
+                del params[key]
         elif isinstance(value, Iterable) and not isinstance(value, str):
-            query_dict.setlist(key, value)
+            params.setlist(key, value)
         else:
-            query_dict[key] = value
-    if not query_dict:
+            params[key] = value
+    if not params and not query_dict:
         return ""
-    query_string = query_dict.urlencode()
+    query_string = params.urlencode()
     return f"?{query_string}"
 
 

+ 1 - 1
docs/ref/templates/builtins.txt

@@ -963,7 +963,7 @@ This tag requires a :class:`~django.http.QueryDict` instance, which defaults to
 :attr:`request.GET <django.http.HttpRequest.GET>` if none is provided.
 
 If the :class:`~django.http.QueryDict` is empty and no additional parameters
-are provided, an empty string is returned. A non-empty result includes a
+are provided, an empty string is returned. Otherwise, the result includes a
 leading ``"?"``.
 
 .. admonition:: Using ``request.GET`` as default

+ 3 - 1
docs/releases/5.1.7.txt

@@ -9,4 +9,6 @@ Django 5.1.7 fixes several bugs in 5.1.6.
 Bugfixes
 ========
 
-* ...
+* Fixed a bug in Django 5.1 where the ``{% querystring %}`` template tag
+  returned an empty string rather than ``"?"`` when all parameters had been
+  removed from the query string (:ticket:`36182`).

+ 12 - 0
tests/template_tests/syntax_tests/test_querystring.py

@@ -20,6 +20,18 @@ class QueryStringTagTests(SimpleTestCase):
             "test_querystring_empty_get_params", context, expected=""
         )
 
+    @setup({"test_querystring_remove_all_params": "{% querystring a=None %}"})
+    def test_querystring_remove_all_params(self):
+        non_empty_context = RequestContext(self.request_factory.get("/?a=b"))
+        empty_context = RequestContext(self.request_factory.get("/"))
+        for context, expected in [(non_empty_context, "?"), (empty_context, "")]:
+            with self.subTest(expected=expected):
+                self.assertRenderEqual(
+                    "test_querystring_remove_all_params",
+                    context,
+                    expected,
+                )
+
     @setup({"test_querystring_non_empty_get_params": "{% querystring %}"})
     def test_querystring_non_empty_get_params(self):
         request = self.request_factory.get("/", {"a": "b"})