mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	Fixed #36268 -- Added leading ? in every querystring template tag result.
				
					
				
			Thanks Sarah Boyce for the report.
This commit is contained in:
		| @@ -1182,6 +1182,8 @@ def querystring(context, query_dict=None, **kwargs): | ||||
|     `request.GET`). Keyword arguments are processed sequentially, with later | ||||
|     arguments taking precedence. | ||||
|  | ||||
|     A query string prefixed with `?` is returned. | ||||
|  | ||||
|     For example:: | ||||
|  | ||||
|         {# Set a parameter on top of `request.GET` #} | ||||
| @@ -1207,9 +1209,7 @@ def querystring(context, query_dict=None, **kwargs): | ||||
|             params.setlist(key, value) | ||||
|         else: | ||||
|             params[key] = value | ||||
|     if not params and not query_dict: | ||||
|         return "" | ||||
|     query_string = params.urlencode() | ||||
|     query_string = params.urlencode() if params else "" | ||||
|     return f"?{query_string}" | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -967,9 +967,8 @@ Outputs a URL-encoded formatted query string based on the provided parameters. | ||||
| 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. Otherwise, the result includes a | ||||
| leading ``"?"``. | ||||
| The result always includes a leading ``"?"`` since this tag is mainly used for | ||||
| links, and an empty result could prevent the page from reloading as expected. | ||||
|  | ||||
| .. admonition:: Using ``request.GET`` as default | ||||
|  | ||||
| @@ -979,6 +978,10 @@ leading ``"?"``. | ||||
|     ``request`` object into the template context, or provide a ``QueryDict`` | ||||
|     instance to this tag. | ||||
|  | ||||
| .. versionchanged:: 6.0 | ||||
|  | ||||
|     A ``?`` was prepended to the query string for empty results. | ||||
|  | ||||
| Basic usage | ||||
| ~~~~~~~~~~~ | ||||
|  | ||||
| @@ -986,8 +989,9 @@ Basic usage | ||||
|  | ||||
|     {% querystring %} | ||||
|  | ||||
| Outputs the current query string verbatim. So if the query string is | ||||
| ``?color=green``, the output would be ``?color=green``. | ||||
| Outputs the current query string verbatim. So if the query string in the | ||||
| request is ``?color=green``, the output would be ``?color=green``. If the | ||||
| current query string is empty, the output will be ``?``. | ||||
|  | ||||
| .. code-block:: html+django | ||||
|  | ||||
| @@ -1038,7 +1042,7 @@ Custom QueryDict | ||||
|  | ||||
| You can provide a custom ``QueryDict`` to be used instead of ``request.GET``. | ||||
| So if ``my_query_dict`` is ``<QueryDict: {'color': ['blue']}>``, this outputs | ||||
| ``?color=blue``. | ||||
| ``?color=blue``. If ``my_query_dict`` is empty, the output will be ``?``. | ||||
|  | ||||
| Dynamic usage | ||||
| ~~~~~~~~~~~~~ | ||||
|   | ||||
| @@ -233,6 +233,9 @@ Templates | ||||
| * The new variable ``forloop.length`` is now available within a :ttag:`for` | ||||
|   loop. | ||||
|  | ||||
| * The :ttag:`querystring` template tag now consistently prefixes the returned | ||||
|   query string with a ``?``, ensuring reliable link generation behavior. | ||||
|  | ||||
| Tests | ||||
| ~~~~~ | ||||
|  | ||||
|   | ||||
| @@ -16,17 +16,15 @@ class QueryStringTagTests(SimpleTestCase): | ||||
|     @setup({"querystring_empty_get_params": "{% querystring %}"}) | ||||
|     def test_querystring_empty_get_params(self): | ||||
|         context = RequestContext(self.request_factory.get("/")) | ||||
|         self.assertRenderEqual("querystring_empty_get_params", context, expected="") | ||||
|         self.assertRenderEqual("querystring_empty_get_params", context, expected="?") | ||||
|  | ||||
|     @setup({"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( | ||||
|                     "querystring_remove_all_params", context, expected | ||||
|                 ) | ||||
|         for context in [non_empty_context, empty_context]: | ||||
|             with self.subTest(context=context): | ||||
|                 self.assertRenderEqual("querystring_remove_all_params", context, "?") | ||||
|  | ||||
|     @setup({"querystring_non_empty_get_params": "{% querystring %}"}) | ||||
|     def test_querystring_non_empty_get_params(self): | ||||
| @@ -46,10 +44,20 @@ class QueryStringTagTests(SimpleTestCase): | ||||
|     def test_querystring_empty_params(self): | ||||
|         cases = [None, {}, QueryDict()] | ||||
|         request = self.request_factory.get("/") | ||||
|         qs = "?a=b" | ||||
|         request_with_qs = self.request_factory.get(f"/{qs}") | ||||
|         for param in cases: | ||||
|             # Empty `query_dict` and nothing on `request.GET`. | ||||
|             with self.subTest(param=param): | ||||
|                 context = RequestContext(request, {"qd": param}) | ||||
|                 self.assertRenderEqual("querystring_empty_params", context, expected="") | ||||
|                 self.assertRenderEqual( | ||||
|                     "querystring_empty_params", context, expected="?" | ||||
|                 ) | ||||
|             # Empty `query_dict` and a query string in `request.GET`. | ||||
|             with self.subTest(param=param, qs=qs): | ||||
|                 context = RequestContext(request_with_qs, {"qd": param}) | ||||
|                 expected = "?" if param is not None else qs | ||||
|                 self.assertRenderEqual("querystring_empty_params", context, expected) | ||||
|  | ||||
|     @setup({"querystring_replace": "{% querystring a=1 %}"}) | ||||
|     def test_querystring_replace(self): | ||||
|   | ||||
		Reference in New Issue
	
	Block a user