Flask - how to get query string parameters into the route parameters

13.6k views Asked by At

Im very much new to Flask, and one of the starting requirements is that i need SEO friendly urls.
I have a route, say

@app.route('/sales/')
@app.route(/sales/<address>)
def get_sales(addr):
  # do some magic here
  # render template of sales

and a simple GET form that submits an address.

<form action={{ url_for('get_sales') }}> 
 <input type='text' name='address'>
 <input type=submit>
</form>

On form submission, the request goes to /sales/?address=somevalue and not to the standard route. What options do I have to have that form submit to /sales/somevalue ? I feel like I'm missing something very basic.

3

There are 3 answers

3
Steve Rossiter On BEST ANSWER

You would need to use JavaScript to achieve this so your template would become:

<input type='text' id='address'>
 <button onclick="sendUrl();">submit</button>


<script>
    function sendUrl(){
        window.location.assign("/sales/"+document.getElementById("address").value);
    }
</script>

and your routes similar to before:

@app.route('/sales/')
@app.route('/sales/<address>')
def get_sales(address="Nowhere"):
  # do some magic here
  # render template of sales
  return "The address is "+address

However, this is not the best way of doing this kind of thing. An alternative approach is to have flask serve data and use a single-page-application framework in javascript to deal with the routes from a user interface perspective.

0
davidism On

There is a difference between the request made when the form is submitted and the response returned. Leave the query string as is, as that is the normal way to interact with a form. When you get a query, process it then redirect to the url you want to display to the user.

@app.route('/sales')
@app.route('/sales/<address>')
def sales(address=None):
    if 'address' in request.args:
        # process the address
        return redirect(url_for('sales', address=address_url_value)

    # address wasn't submitted, show form and address details
0
junnytony On

I'm not sure there's a way to access the query string like that. The route decorators only work on the base url (minus the query string)

If you want the address in your route handler then you can access it like this:

request.args.get('address', None)

and your route handler will look more like:

@pp.route('/sales')
def get_sales():
    address = request.args.get('address', None)

But if I were to add my 2 cents, you may want to use POST as the method for your form posting. It makes it easier to semantically separate getting data from the Web server (GET) and sending data to the webserver (POST) :)