Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python flask array querystring in url_for

Tags:

python

flask

I can't find any information about generating a url using array querystrings like so: http://www.domain.com?page[limit]=20&page[offset]=0

I tried this:

url_for(endpoint, page={'limit': 0, 'offset': 0}, _external=True)

But it generated the following url:

http://www.domain.com?page={'limit': 0, 'offset': 0}

My current solution is as follows:

querystrings = []
querystrings.append('page[limit]=%d' % (limit))
querystrings.append('page[offset]=%d' % (offset))
url = '%s?%s' % (root_url, '&'.join(querystrings))

I really hope there is a better way!

Any help would be appreciated!


Edit

I ended up creating a wrapper which handles the dicts separately, based on my previous solution:

from flask import g, url_for as _url_for

def url_for(endpoint, **values):
    # fix querystring dicts
    querystring_dicts = []
    for key, value in list(values.items()):
        if isinstance(value, dict):
            for _key, _value in list(value.items()):
                querystring_dicts.append('%s[%s]=%s' % (key, _key, _value))
            values.pop(key)

    # create url
    url = _url_for(endpoint, **values)

    # append querystring dicts
    if querystring_dicts:
        seperator = '?'
        if '?' in url:
            seperator = '&'
        url = '%s%s%s' % (url, seperator, '&'.join(querystring_dicts))

    return url

I then call the wrapper like so:

url_for(endpoint, page={'limit': 20, 'offset': 0}, _external=True)

And it will return the following url:

http://www.domain.com?page[limit]=20&page[offset]=0

like image 880
Nixxxon Avatar asked Feb 07 '26 20:02

Nixxxon


1 Answers

I don't believe what you're attempting is supported out of the box. Under the hood url_for is relying on Werkzeug's URL routing converters to generate and encode these values and there doesn't appear to be an encoder for dictionaries (minor aside, that is what that {key: value} syntax denotes, it's not an array).

I found this blurb which outlines the implementation of custom converters if you want to add support yourself. The Flask project may even be happy to get a PR if you go that route, however unless you have some need to use page[limit] rather than page_limit I would just change them.

url_for(endpoint, page_offset = 0, page_limit=0, _external=True)
like image 72
phro Avatar answered Feb 09 '26 12:02

phro