3

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

2
  • How is your input stored? Commented Apr 26, 2015 at 23:26
  • Hi! Could you please explain what you mean? Commented Apr 27, 2015 at 18:46

1 Answer 1

3

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)
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your help! I ended up creating a wrapper which converts the dicts to the correct format and then calls the real url_for function. I have added my solution above. Actually, this should really be supported out of the box... I will consider a PR if I get the time!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.