Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Altering one query parameter in a url (Django)

I have a search page that takes a variety of parameters. I want to create a new URL by just altering one parameter in the query. Is there an easy way to do this - something like:

# example request url
http://example.com/search?q=foo&option=bar&option2=baz&change=before

# ideal template code
{% url_with change 'after' %}

# resulting url
http://example.com/search?q=foo&option=bar&option2=baz&change=after

So this would take the request url, alter one query parameter and then return the new url. Similar to what can be achieved in Perl's Catalyst using $c->uri_with({change => 'after'}).

Or is there a better way?

[UPDATED: removed references to pagination]

like image 922
EvdB Avatar asked Apr 22 '11 11:04

EvdB


People also ask

How can the parameters in a URL be edited?

The value of a parameter can be updated with the set() method of URLSearchParams object. After setting the new value you can get the new query string with the toString() method. This query string can be set as the new value of the search property of the URL object.

How do you specify a parameter in a URL?

To add a parameter to the URL, add a /#/? to the end, followed by the parameter name, an equal sign (=), and the value of the parameter. You can add multiple parameters by including an ampersand (&) between each one.

How can I append a query parameter to an existing URL?

append() The append() method of the URLSearchParams interface appends a specified key/value pair as a new search parameter. As shown in the example below, if the same key is appended multiple times it will appear in the parameter string multiple times for each value.

How can URL have multiple query parameters?

Any word after the question mark (?) in a URL is considered to be a parameter which can hold values. The value for the corresponding parameter is given after the symbol "equals" (=). Multiple parameters can be passed through the URL by separating them with multiple "&".


2 Answers

I did this simple tag which doesn't require any extra libraries:

@register.simple_tag
def url_replace(request, field, value):

    dict_ = request.GET.copy()

    dict_[field] = value

    return dict_.urlencode()

Use as:

<a href="?{% url_replace request 'param' value %}">

It wil add 'param' to your url GET string if it's not there, or replace it with the new value if it's already there.

You also need the RequestContext request instance to be provided to your template from your view. More info here:

http://lincolnloop.com/blog/2008/may/10/getting-requestcontext-your-templates/

like image 74
mpaf Avatar answered Sep 18 '22 09:09

mpaf


So, write a template tag around this:

from urlparse import urlparse, urlunparse
from django.http import QueryDict

def replace_query_param(url, attr, val):
    (scheme, netloc, path, params, query, fragment) = urlparse(url)
    query_dict = QueryDict(query).copy()
    query_dict[attr] = val
    query = query_dict.urlencode()
    return urlunparse((scheme, netloc, path, params, query, fragment))

For a more comprehensive solution, use Zachary Voase's URLObject 2, which is very nicely done.

Note: The urlparse module is renamed to urllib.parse in Python 3.

like image 45
Tom Christie Avatar answered Sep 22 '22 09:09

Tom Christie