tadm123
tadm123

Reputation: 8787

Flask - Getting values

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.

Upvotes: 2

Views: 5111

Answers (1)

abigperson
abigperson

Reputation: 5362

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

Upvotes: 2

Related Questions