Dynamically pull query in FLASK

Question:

I have a small application built in flask and also I am new to it and hence learning it
Appreciate if you could help me solve below ask.

Right now, the all contents in the dataframe(2 rows) are displayed. Is there a way to display only what is selected in the dropdown(say ‘Karan’ so only row with Karan should be displayed)

app.py

from flask import Flask, render_template
import pandas as pd
import sqlalchemy as sal
from sqlalchemy import create_engine
import pyodbc 
import urllib

##conn = pyodbc.connect('Driver={SQL Server Native client 11.0};server=localhost;database=Nifty;trusted_connection=yes;')

params = urllib.parse.quote_plus("DRIVER={SQL Server Native Client 11.0};"
                                 "SERVER=localhost;"
                                 "DATABASE=Nifty;"
                                 "Trusted_Connection=yes")

engine = sal.create_engine("mssql+pyodbc:///?odbc_connect={}".format(params))
##sql_query = pd.read_sql_query('select  top 1 * from [dbo].ABC', engine)

app = Flask(__name__)

read_df = pd.read_excel('List_500_companies.xlsx') ## getting list r
#list_ticker = read_df['symbol'].tolist()
list_ticker = ['Karan', 'Rohit']


## Getting column names from DB

data_values = [['Karan',23],['Rohit',22]]
col_names = pd.DataFrame(data_values,columns=['Name','Age'])


#col_names = pd.read_sql_query('select  top 5 * from [dbo].[3MINDIA]', engine)


headings = col_names
data = col_names.values



@app.route('/', methods=['GET'])
def dropdown():
    get_list_name = list_ticker
    return render_template('template.html', tickers = get_list_name, heading_name = headings, data_name = data)

if __name__ == "__main__":
    app.run(port = 8080)

template.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Dropdown</title>
</head>
<body>
<select onchange="update_selected_option_value(value)">
    {% for ticker in tickers %}<option value="{{ticker}}" SELECTED>{{ticker}}</option>{% endfor %}
</select>
<br></br>



<table>
  <tr>{% for header in heading_name %}<th>{{header}}</th>{% endfor %}</tr>
  {% for row in data_name %}<tr>{% for cell in row %}<td>{{cell}}</td>{% endfor %}</tr>{% endfor %}
</table>


<script>function update_selected_option_value(value) {
  document.getElementById('res_head').innerHTML = value;
  document.getElementById('res_data').innerHTML = value;
}</script>
</body>
</html>
Asked By: user11740857

||

Answers:

The following example shows you how you can use the form data transmitted via a GET request to filter your DataFrame.
The user can select several entries from a list of names and submit the form. All selected entries are now queried on the server side using the name of the form field. Then the rows of the DataFrame are filtered in which the "Name" column occurs within the list of selected entries. All resulting rows are displayed.

from flask import (
    Flask, 
    render_template, 
    request
)
import pandas as pd

df = pd.DataFrame(
    [
        ['Karan', 23],
        ['Rohit', 22]
    ],
    columns=['Name', 'Age']
)

@app.route('/')
def index():
    names = df['Name'].tolist()

    tickers = request.args.getlist('tickers') or names
    data = df[df['Name'].isin(tickers)]

    return render_template('index.html', **locals())
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title></title>
</head>
<body>
    <form>
        <select name="tickers" multiple>
            {% for name in names -%}
            <option value="{{ name }}" {% if name in tickers -%}selected{% endif -%}>{{ name }}</option>
            {% endfor -%}
        </select>
        <button type="submit">Submit</button>
    </form>
    <hr />

    <table border="1" width="100%">
        <thead>
            <tr>
                {% for column in data.columns -%}
                <th>{{ column }}</th>
                {% endfor -%}
            </tr>
        </thead>
        <tbody>
            {% for row in data.values -%}
            <tr>
                {% for cell in row -%}
                <td>{{ cell }}</td>
                {% endfor -%}
            </tr>
            {% endfor -%}
        </tbody>
    </table>
</body>
</html>

If you want to use POST as the request method, the example looks like this.

from flask import (
    Flask, 
    render_template, 
    request
)
import pandas as pd

df = pd.DataFrame(
    [
        ['Karan', 23],
        ['Rohit', 22]
    ],
    columns=['Name','Age']
)

@app.route('/', methods=['GET', 'POST'])
def index():
    names = df['Name'].tolist()
    tickers = names
    if request.method == 'POST':
        tickers = request.form.getlist('tickers') or names
    data = df[df['Name'].isin(tickers)]
    return render_template('index.html', **locals())
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title></title>
</head>
<body>
    <form method="POST">
        <select name="tickers" multiple>
            {% for name in names -%}
            <option value="{{ name }}" {% if name in tickers -%}selected{% endif -%}>{{ name }}</option>
            {% endfor -%}
        </select>
        <button type="submit">Search</button>
    </form>

    <hr />

    <table border="1" width="100%">
        <thead>
            <tr>
                {% for column in data.columns -%}
                <th>{{ column }}</th>
                {% endfor -%}
            </tr>
        </thead>
        <tbody>
            {% for row in data.values -%}
            <tr>
                {% for cell in row -%}
                <td>{{ cell }}</td>
                {% endfor -%}
            </tr>
            {% endfor -%}
        </tbody>
    </table>
</body>
</html>
Answered By: Detlef
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.