Peter
Peter

Reputation: 3495

Issue with url_for mapping variables to URL if multiple routes are used

I've hit an issue with url_for, where it won't automatically remap the variable straight into the URL because there are two routes.

My use case is an API, where creating an object will return the same data as if a GET command was run on it.

Here's an example of the code:

@app.route('/test', methods=['POST'])
@app.route('/test/<string:name>', methods=['GET'])
def test(name=None):
    if request.method == 'POST':
        return redirect(url_for('test', name='xyz'))
    return name

If the first app.route is removed, then url_for('test', name='xyz') will correctly return "test/xyz".

However, with both app.route lines, it instead returns "test?name=xyz". This then causes name to be None, where the variable is actually located at request.args['name'].

I don't want to do a if name is None: name=request.args.get('name'), so is there any way I can force it to only look at routes with a GET method? My case right now is simple enough I could just do url_for('test')+'/xyz', but it seems like there should be better way of doing this.

Upvotes: 0

Views: 337

Answers (1)

Dan Safee
Dan Safee

Reputation: 1618

According to the Flask Docs you can specify which method to map against use the _method argument.

flask.url_for(endpoint, **values)

And the values you can pass are:

  • endpoint – the endpoint of the URL (name of the function)
  • values – the variable arguments of the URL rule
  • _external – if set to True, an absolute URL is generated. Server address can be changed via SERVER_NAME configuration variable which falls back to the Host header, then to the IP and port of the request.
  • _scheme – a string specifying the desired URL scheme. The _external parameter must be set to True or a ValueError is raised. The default behavior uses the same scheme as the current request, or PREFERRED_URL_SCHEME from the app configuration if no request context is available. As of Werkzeug 0.10, this also can be set to an empty string to build protocol-relative URLs.
  • _anchor – if provided this is added as anchor to the URL.
  • _method – if provided this explicitly specifies an HTTP method. <---- This one

Specify the _method argument in url_for like this:

url_for('test', name='xyz', _method='GET')

Upvotes: 1

Related Questions