Flask – Getting values

Question:

I want to get the “name” and “size” values from what the user typed into a search box.

But the obvious problems are that I’m trying to get values from a method: "POST" hmtl form.
And my html action just references the {{ url_for('main') }} html not where want to retrieve these values in the {{ url_for(‘search’) }} html.

Here are the templates:

import sqlite3
from flask import Flask,render_template, url_for, redirect, request


app = Flask(__name__)
conn = sqlite3.connect('shoes.db', check_same_thread=False)
c = conn.cursor()

@app.route("/", methods=["GET", "POST"])
def main():

    if request.method == 'GET':
        return render_template('main.html')

    elif request.method == 'POST':
        name = request.form.get('name')
        size = request.form.get('size')
        return redirect(url_for('search'))


@app.route("/search/", methods=["GET", "POST"])
def search():

    # Need to get the 'name' and 'search' values from input, so this way is incorrect.
    name = request.args.get("name") 
    size = request.args.get("size")     

    c.execute("SELECT * FROM shoes WHERE name LIKE ? AND sizes LIKE ? ORDER BY price",
                    ('%'+name+'%','%'+size+'%'))

    p = c.fetchall()

    url = [p[i][0] for i in range(len(p))]
    names = [p[i][1] for i in range(len(p))]
    prices = [p[i][2] for i in range(len(p))]
    sizes = [p[i][3] for i in range(len(p))]
    shoe_type = [p[i][4] for i in range(len(p))]

    return render_template('search.html' , url=url, names=names, prices=prices,
                           sizes=sizes, shoe_type=shoe_type)


if __name__ == '__main__':
    app.run(debug=True)

main.html:

{% extends "layout.html" %}
{% block content %}

<form action = "{{ url_for('main') }}" class="form" method = "POST" >

        <h1>Soccer Shoes Finder</h1>
        <div class="line-separator"></div>

            <div class="container-fluid">
                <input name = "name" type="text" placeholder="Name"/>
                <input name = "size" type="text" placeholder="Size"/>
                <button class="glyphicon glyphicon-search" aria-hidden="true"></button>
            </div>

</form>

{% endblock %}

search.html:

{% extends "layout.html" %}
{% block content %}


    <div class= "container">
    <h2>Results:</h2>
    <table class="table table-striped">
    <thead>
    <tr>
        <th>url</th>
        <th>Name</th>
        <th>Prices</th>
        <th>Sizes</th>
        <th>Shoe Type</th>
    </tr>
    </thead>
    <tbody>
    {% for i in range(url|length) %}
    <tr>
        <td><a href={{url[i]}}>aa</td>
        <td>{{names[i]}}</td>
        <td>${{prices[i]}}</td>
        <td>{{sizes[i]}}</td>
        <td>{{shoe_type[i]}}</td>
    </tr>
    {% endfor %}
    </tbody>
    </table>
    </div>
{% endblock %}

Anyone know how could I achieve this? Hopefully what I said makes sense. Thanks.

Asked By: tadm123

||

Answers:

Simplify your main route, seems there is no reason to POST the data here:

@app.route("/")
def main():
    return render_template('main.html')

POST the data instead directly to your search endpoint by changing this line within your main.html Jinja template:

<form action="{{ url_for('search') }}" class="form" method="POST">

Since this page rendering is dependent on having form data I’d just set it to only accept POST methods, but this is up to you. You need to access the values here using request.form (or request.values if you also want to support query string GET method).

@app.route("/search/", methods=["POST"])
def search():
    name = request.form.get("name") 
    size = request.form.get("size")

Assuming your database code works the rest of this should work as expected

Answered By: abigperson
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.