mirror of
https://github.com/django/django.git
synced 2025-04-08 15:36:47 +00:00
Fixed #36268 -- Added leading ?
in every querystring template tag result.
Thanks Sarah Boyce for the report.
This commit is contained in:
parent
b1c1fd33ed
commit
0b4f2d8d39
@ -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):
|
||||
|
Loading…
x
Reference in New Issue
Block a user