152

I'd like to add request parameters to a {% url %} tag, like ?office=foobar.

Is this possible? I can't find anything on it.

keturn
  • 4,780
  • 3
  • 29
  • 40
Brian D
  • 9,863
  • 18
  • 61
  • 96

7 Answers7

223

No, because the GET parameters are not part of the URL.

Simply add them to the end:

<a href="{% url myview %}?office=foobar">

For Django 1.5+

<a href="{% url 'myview' %}?office=foobar">
eos87
  • 8,961
  • 12
  • 49
  • 77
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • 15
    Well, technically they are. According to [RFC 1738](http://www.ietf.org/rfc/rfc1738.txt), an HTTP URL takes the form: http://:/?. – naktinis May 18 '12 at 16:53
  • @naktinis An HTTP URL, yes. A Django URL, [not so much](https://docs.djangoproject.com/en/1.4/topics/http/urls/#how-django-processes-a-request). So for various definitions of "URL", you are both correct :P –  Nov 30 '12 at 16:37
  • Doesn't this result in the trailing slash interrupting the url, like `example.com/myview/?office=foobar` instead of `example.com/myview?office=foobar`? – Al Sweigart May 12 '17 at 02:28
  • Yes but so what? – Daniel Roseman May 12 '17 at 06:57
  • Imagine I want to nest query parameters, elegantly, how can I achieve that? – Andrés Quiroz Valdovinos Nov 30 '21 at 03:34
46

A way to mix-up current parameters with new one:

{% url 'order_list' %}?office=foobar&{{ request.GET.urlencode }}

Modify your settings to have request variable:

from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS as TCP

TEMPLATE_CONTEXT_PROCESSORS = TCP + (
    'django.core.context_processors.request',
)
eri
  • 3,133
  • 1
  • 23
  • 35
37

Use urlencode if the argument is a variable

<a href="{% url 'myview' %}?office={{ some_var | urlencode }}">

or else special characters like spaces might break your URL.

Documentation: https://docs.djangoproject.com/en/3.0/ref/templates/builtins/#urlencode

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
  • This doesn't work for me.. the `some_var` variable returns empty in the href but is shown to be filled if used elsewhere in the template. v2.1 – geoidesic Aug 30 '18 at 14:43
  • @geoidesic thanks for the report, let me know if you find further the breaking commit / version release notes, or manage to reproduce on 1.9. – Ciro Santilli OurBigBook.com Aug 30 '18 at 14:46
9

First, a silly answer:

{% url my-view-name %}?office=foobar

A serious anwser: No, you can't. Django's URL resolver matches only the path part of the URL, thus the {% url %} tag can only reverse that part of URL.

lqc
  • 7,434
  • 1
  • 25
  • 25
  • Indeed. That makes sense too ... I just wish it was a little more elegant than that. – Brian D Jan 04 '11 at 08:06
  • You could always write a more elegant custom tag - {% qpurl myview office=foobar %} for example. This could also process the values and encode them appropriately. – Spacedman Jan 04 '11 at 09:02
2

If your url (and the view) contains variable office then you can pass it like this:

{% url 'some-url-name' foobar %}

or like this, if you have more than one parameter:

{% url 'some-url-name' office='foobar' %}

Documentation: https://docs.djangoproject.com/en/3.1/ref/templates/builtins/#url

1

Tried all the above, nothing worked.
My system has:

  • Python 3.8.10
  • python3 -m django --version 4.0.3

Here's what worked for me:
urls.py

urlpatterns = [
    path('', views.index, name='index'),
    path('single/', views.single, name='single'),
]

views.py

def single(request):
    url = request.GET.get('url')
    return HttpResponse(url)

Calling from .html file

<a href={% url 'single' %}?url={{url}} target="_self">

Broswer URL

http://127.0.0.1:8000/newsblog/single/?url=https://www.cnn.com/2022/08/16/politics/liz-cheney-wyoming-alaska-primaries/index.html

Output

Jadeye
  • 3,551
  • 4
  • 47
  • 63
0

Try this:

{% url 'myview' office=foobar %}

It worked for me. It basically does a reverse on that link and applies the given arguments.