Cerin
Cerin

Reputation: 64820

Django template tag to insert or replace URL parameter

Is anyone aware of a Django template tag that takes the current path and query string and inserts or replaces a query string value?

e.g. given a request to /some/custom/path?q=how+now+brown+cow&page=3&filter=person

The call {% urlparam 'page' 4 %} would generate /some/custom/path?q=how+now+brown+cow&page=4&filter=person.

This wouldn't be too difficult to write from scratch, but as this seems like a very common task, I would expect a tag like this to be built-in. However, after reading through the docs and googling, I can't seem to find anyone's who's publicized such a tag.

Upvotes: 5

Views: 4622

Answers (3)

Burhan Khalid
Burhan Khalid

Reputation: 174692

I want to render a series of pagination links on a search page. The URL contains several query parameters (like in my example). The pagination code that renders the pagination links shouldn't have to be explicitly given all these parameters. Django's admin seems to have this behavior everywhere.

This is enabled by adding django.core.context_processors.request to TEMPLATE_CONTEXT_PROCESSORS (its not enabled by default). This will add a request variable to your templates, which is the HttpRequest object.

From there, you can use {{ request.get_full_path }} to get the current URL with the complete query string, and then append your custom query to it.

If your page is /search?q=foo+bar, and you want a new link to be /search?q=foo+bar&page=4, <a href="{{ request.get_full_path }}&page=4">page 4</a>.

Upvotes: 1

alecxe
alecxe

Reputation: 474121

Since I haven't used these tools by my own, I'll just refer you:

FYI, I've personally used jsurl library for this kind of url manipulations in javascript.

Hope that helps.

Upvotes: 4

Eric Clack
Eric Clack

Reputation: 1926

Here's how I did it on a Django 1.3 project. Like you I expected to find this built in, but ended up coding it in the view:

def remove_url_param(url, params):
    if not isinstance(params, list):
        params = [params,]
    if isinstance(url, unicode):
        # urlencode doesn't like unicode
        url = url.encode('utf8')

    (scheme, netloc, path, query, fragment) = urlparse.urlsplit(url)
    param_dict = parse_qs(query)
    for p in params:
        try:
            del(param_dict[p])
        except KeyError:
            pass
    query = urllib.urlencode(param_dict, True)
    return urlparse.urlunsplit((scheme, netloc, path, query, fragment))

Then I used this to create base URLs:

page_url_unordered = putils.remove_url_param( request.get_full_path(), ['order', 'ajax'] )

Then in the template:

<a href="{{ page_url_unordered }}&amp;order=price">Price</a>
<a href="{{ page_url_unordered }}&amp;order=size">Size</a>

Upvotes: 1

Related Questions