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