Opened 3 weeks ago
Closed 3 weeks ago
#36941 closed Cleanup/optimization (invalid)
Enhancement Proposal for querystring template tag: Support for dynamic context-based keys
| Reported by: | Hristo Trendafilov | Owned by: | Vishy Algo |
|---|---|---|---|
| Component: | Template system | Version: | 5.2 |
| Severity: | Normal | Keywords: | |
| Cc: | Yogya Chugh | Triage Stage: | Unreviewed |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Problem Statement
Currently, the {% querystring %} template tag treats the keys in kwargs as static strings. While this works for simple use cases, it severely limits the reusability of templates in component-based architectures.
When using {% include %} to render a reusable component (like a generic filter, a sortable table header, or a pagination widget), the parameter name (the key) often needs to be dynamic, just like the value.
The Use Case
Imagine a reusable include for a sortable column: sort_link.html
<a href="{% querystring sort_param=field_name %}">
Sort by {{ field_label }}
</a>
If we include it like this:
{% include 'sort_link.html' with sort_param='order_by' field_name='price' field_label='By Price' %}
Current Behaviour: It produces ?sort_param=price.
Expected/Desired Behaviour: It should produce ?order_by=price.
Proposed Solution
Add an optional boolean parameter resolve_keys (or similar) to the querystring tag. When set to True, the tag will look up the key names in the current context before processing the query dict.
Alternatively, there could be a dedicated template tag that reuses the current querystring
@register.simple_tag(takes_context=True)
def querystring(context, query_dict=None, resolve_keys=False, **kwargs):
# ... existing logic ...
for _key, value in kwargs.items():
# Look up the key name in context if the flag is True
key = context.get(_key) if resolve_keys else _key
if key is None:
# suggested behaviour - remove this key if in parameters, like if passed `key=None`
# ... correct logic continues ...
Benefits
Decoupling: Templates don't need to know the specific backend parameter names.
DRY: One include can handle different filtering/sorting logic across different views.
Consistency: Aligns with how Django handles dynamic values, extending that logic to keys.
Change History (8)
comment:1 by , 3 weeks ago
| Description: | modified (diff) |
|---|
comment:2 by , 3 weeks ago
| Description: | modified (diff) |
|---|
comment:3 by , 3 weeks ago
| Cc: | added |
|---|
comment:4 by , 3 weeks ago
| Owner: | set to |
|---|---|
| Status: | new → assigned |
comment:5 by , 3 weeks ago
follow-up: 7 comment:6 by , 3 weeks ago
Has this got consensus? It would be better to raise this on the Django Forum first.
comment:7 by , 3 weeks ago
Replying to Vishy Algo:
Has this got consensus? It would be better to raise this on the Django Forum first.
I think this is a needed update to make this template tag more dynamic, reusable and comply better with the Django template inheritance.
comment:8 by , 3 weeks ago
| Easy pickings: | unset |
|---|---|
| Has patch: | unset |
| Resolution: | → invalid |
| Status: | assigned → closed |
Thanks for the ticket. Both querystring and the {% with %} tag are working as expected, but they don’t support dynamic parameter names, so they won’t produce the exact output you’re looking for.
You should be able to achieve what you want by writing a custom template tag that takes a parameter name and value, builds the query string in Python, and returns the correct URL. You'd then replace querystring in your include template with that tag (which potentially might be a simple wrapper around querystring.
Closing this ticket per https://code.djangoproject.com/wiki/TicketClosingReasons/UseSupportChannels. If you want to propose a change to the template language syntax itself, you’d have to open a new feature proposal/suggestion per this documentation.
If needed, I could give a hand with that as well.