0

I'm trying to create complex routing for a get request that looks like this:

@app.route('/get-details?id=<int:id>&code=<int:code>', methods=['GET'])
@login_required
def get_details(id, code):
    # Do something with code and id ....

And in my template I have a form that looks like this:

<form action="{{url_for('get_details')}}" method="get">
    {{ form.hidden_tag() }}
    {{ form.id() }}
    {{ form.code() }}
    <input type="submit">

</form>

But when I try to render my page I get this exception:

  File "/home/sharon/dev/wiseart/credixdealer/app/templates/dashboard/form-device.html", line 113, in block "content"
    <form action="{{url_for('get_details')}}" method="get">
  File "/usr/local/lib/python2.7/dist-packages/flask/helpers.py", line 332, in url_for
    return appctx.app.handle_url_build_error(error, endpoint, values)
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1811, in handle_url_build_error
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python2.7/dist-packages/flask/helpers.py", line 322, in url_for
    force_external=external)
  File "/usr/local/lib/python2.7/dist-packages/werkzeug/routing.py", line 1758, in build
    raise BuildError(endpoint, values, method, self)
BuildError: Could not build url for endpoint 'get_details'. Did you forget to specify values ['business_id', 'id']?

How can I specify in url_for that the parameters should be retrieved from the form itself?

scott_lotus
  • 3,171
  • 22
  • 51
  • 69
Sharon Lifshits
  • 453
  • 4
  • 9
  • '/get-details?id=&code='... Why are you creating complexities. This can be done in a very simplistic way. – Hassan Mehmood Jun 23 '16 at 11:37
  • 1
    Werkzeug routing underlying `app.route()` does mention `query_args` in the docs, but also has this to say: "query_args – optional query arguments that are used for automatic redirects as string or dictionary. It’s currently not possible to use the query arguments for URL matching." I think what you're trying to do is impossible in Flask at this time. Have you tried [Pyramid](http://docs.pylonsproject.org/projects/pyramid/en/latest/)? – Ilja Everilä Jun 23 '16 at 11:44
  • 1
    But trolling aside, you should [access query params using `request.args`](http://stackoverflow.com/questions/11774265/flask-how-do-you-get-a-query-string-from-flask). – Ilja Everilä Jun 23 '16 at 11:49
  • thanks! it seems that accessing with request.args solves the problem – Sharon Lifshits Jun 23 '16 at 14:02

1 Answers1

1

Don't put query args in the route definition. Instead, get them from request.args. args.get takes an optional type argument, so you can still validate the type of the value.

@app.route('/get_details')
def get_details():
    id = request.args.get('id', type=int)
    code = request.args.get('code', type=int)
    ...

For the solution to your specific error, read the error message. You have a route with two url groups, but you don't supply values for them to url_for. Since you only know the args after the form is filled out on the client, this becomes a good argument for why you don't put query args in the route.

url_for('get_details', id=2, code=108)
davidism
  • 121,510
  • 29
  • 395
  • 339