Search code examples
flaskjinja2

Flask: url_for with path parameter and query parameter


I have a base.html where all my other pages extend from. In the base.html I want different links with the possibility to add different query parameters to the page I'm currently at.

That is easy with:

url_for(request.endpoint, querypara=value)

I know that I can just add the path parameter also like this:

url_for(request.endpoint, pathpara=value, querypara=value)

But my problem is, that I have different pages with different path parameters.

So page1, for example, would need:

url_for(request.endpoint, pathpara1=value, querypara=value)

page2:

url_for(request.endpoint, pathpara2=value, querypara=value)

And maybe page3 don't need any path parameter:

url_for(request.endpoint, querypara=value)

Is there a way to add both (or just the query) but still be flexible so I don't have to write different Jinja code for every page with path parameters.

I already know how to work around it without the base.html and just not extending every page of it. But I am interested if anyone has a smart solution for it.


Solution

  • Found a way to do it!

    The solution was to combine the following three:

    • request.args (the query arguments that the request received)
    • request.views (the path arguments that we received)
    • possible new arguments

    request.args and request.views each provide a dictionary.

    I wrote a little function that combined all three:

    def combine_view_args(*args):
        dic = {}
        for arg in args:
            dic.update(arg)
        return dic
    

    We give the new possible arguments as a dictionary aswell.

    To access the function in Jinja we need to add it in the context_processor

    @app.context_processor
    def utility_processor():
        return dict(combine_view_args=combine_view_args)
    

    and so we can use all of that in the url_for in the end

    <a href="{{url_for(request.endpoint, **combine_view_args(request.args,request.view_args,{'newArgument':'value'}) )}}">Value</a>