Search code examples
djangotemplatesurlparametersget

Django - passing named parameter to url in template


For some reason I don't understand, when I pass a parameter to my url inside my template, the generated url does not include the parameter keyword "?ts=".

To be clearer, the code below generate as href the url my_view20230511 instead of my_view?ts=20230511. What puzzles me even more is that all urls still work : I mean I can access my_view, my_view20230511 and my_view?ts=20230511

my_view and my_view?ts=20230511 have the behaviour I want which is : the page is same for both but for the second I also have the content of some file rendered

But I don't need my_view20230511 since I would like this line <a href="{% url 'my_view' ts=ts %}">{{ ts_fmt }}</a> to point to my_view?ts=20230511

urls.py

from django.urls import re_path
from . import views

urlpatterns = [
    re_path(r'^my_view(?P<ts>\d+)?$', views.my_view, name = "my_view")
    ]

views.py

def my_view(request, ts=""):
    ts = request.GET.get('ts', "")
    timestamps = [('20230509', datetime(2023,5,9),
                  ('20230510', datetime(2023,5,10),
                  ('20230511', datetime(2023,5,11)]
  
    context = {
        'timestamps' : timestamps,
        'ts' : ts
    }
    
    if ts != "":
        with open(f"filepath/that/depends/on/{ts}", "r") as f:
            lines = f.readlines()
        context['lines'] = lines

    return render(request, 'template.html', context)

template.html

{% for ts,ts_fmt in timestamps %}
   <p><a href="{% url 'my_view' ts=ts %}">{{ ts_fmt }}</a></p>
{% endfor %}

{% if msg %}
      {% for line in lines %}
         <p>{{ line }}</p>
      {% endfor %}
{% endif %}

I can't find any help on this issue so trying my luck on stackoverflow...I hope I made it clear enough to be understood ?

EDIT

First error was trying to declare a query parameter in my urls as Charlesthk pointed out. And second was the way of adding the query parameter to the url from the template. Hence a solution (removing the parameter from urls and views and changing syntax in template) is :

urls.py

from django.urls import re_path
from . import views

urlpatterns = [
    path('my_view', views.my_view, name = "my_view")
    ]

views.py

def my_view(request):
    ts = request.GET.get('ts', "")
    timestamps = [('20230509', datetime(2023,5,9),
                  ('20230510', datetime(2023,5,10),
                  ('20230511', datetime(2023,5,11)]
  
    context = {
        'timestamps' : timestamps,
        'ts' : ts
    }
    
    if ts != "":
        with open(f"filepath/that/depends/on/{ts}", "r") as f:
            lines = f.readlines()
        context['lines'] = lines

    return render(request, 'template.html', context)

template.html

{% for ts,ts_fmt in timestamps %}
   <p><a href="{% url 'admin_mail' %}?ts={{ ts }}">{{ ts_fmt }}</a></p>
{% endfor %}

{% if msg %}
      {% for line in lines %}
         <p>{{ line }}</p>
      {% endfor %}
{% endif %}

Solution

  • In django, query parameters should not be declared in your urls :

    from django.urls import path
    from . import views
    
    urlpatterns = [
       path('my_view', views.my_view, name="my_view")
    ]
    

    With this declaration, both /my_view and /my_view?foo=bar resolve to views.my_view