I totally misunderstood url_for's API, I was expecting url_for('some_route', foo='bar') to return 'http://testserver/my_route/?foo=bar'.
I understand why that is now, but what is the best way to generate urls like this?
(for pagination in a rest list api in this case).
Could url_for grow support for query parameters in addition to path parameters?
Totally agree with you, it would be very convenient.
I propose to add all unmatched path params to query string.
I think what we'll probably do here is have url_for return a URL instance, and add a .with_query_params method to URLs, which would allow for this kind of usage...
url = request.url_for('users', username="tom").with_query_params(...)
Sounds great, but would there be a less wordy alternative?
Perhaps just this...
request.url_for('users', username="tom").with_query(...)Or an explicitly shorthand notation...
request.url_for('users', username="tom").q(...).params() maybe?
We probably want to differentiate it more clearly from the properties on the URL class. (.params might just as well indicate a property on the class. .with_query() makes it kinda clear that it's going to return a new URL.)
I think we probably want to end up with...
.query_params - A QueryParams datastructure..query_string - A raw string..with_query(...) - A new URL.@cjw296 @tomchristie
I see you're taking some care to think this through, so I'll be closing my open PR on this soon (been open for more than a month now) - the approach I took in the PR was more akin to the existing implementation. But I guess you want to refactor in order to provide a more proper support for the URL's query. And I'm defintely :+1: on that
are there any updates?
I implemented a naive workaround to this:
def url_for_query(request: Request, name: str, **params: str) -> str:
url = request.url_for(name)
parsed = list(urllib.parse.urlparse(url))
parsed[4] = urllib.parse.urlencode(params)
return urllib.parse.urlparse(parsed)
templates = Jinja2Templates(directory='templates')
templates.env.globals['url_for_query'] = url_for_query
Then, in template
{ url_for_query('foo', bar='baz') }
This solution doesn't work for routes that accept a parameter.
Most helpful comment
are there any updates?