Build Website with Flask – Part 5


This is part of our Flask series:

Story: Assume you work in the IT Department of Right-On Realtors. Your boss asks you to create a simple website the Realtors can query to view current Home Sales.

He would like this website created using the Flask plugin.

What is Flask?

Flask is a web app framework created with ease-of-use in mind. Without much training, you can easily create a simple web application. Flask works with Bootstrap, HTML, CSS, and Jinja (to name a few) to create a website.


Preparation

This article assumes you have completed the following from Part 1, Part 2, Part 3, and Part 4:

  • Created and Activated a Virtual Environment.
  • Installed all of the required plugins.
  • Created the appropriate folder structure.
  • Created and saved an app.py file to the realtors folder.
  • Added Routes to the app.py file.
  • Added Jinja to the base template.
  • Created and saved HTML files to the realtors/templates folder.
  • Linked to Bootstrap.
  • Added a Bootstrap Navbar to the base template file (base.html).
  • Added Jinja to the HTML pages.
  • Viewed the website in a Browser.
  • Added a Form with elements to an HTML page.
  • Added Jinja to the Reports page.
  • Added code to app.py to get the HTML Form working.

In Part 5, you will learn how to:

  • Read in the Real Estate CSV file to a DataFrame.
  • Then, query the results based on the entered Zip Code.
  • Finally, display the results on the Reports page.

Add the following code to the top of each code snippet. This snippet will allow the code in this article to run error-free.

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

Read CSV & Query DataFrame

Part 4 retrieved the Zip Code entered on the Home page and displayed it back to us on the Reports page. Let’s expand on this.

The next step is to query the DataFrame based on this Zip Code and pass the results to render_template(). Doing this will allow us to display all Home Sales from the selected Zip Code on the Reports page.

app = Flask(__name__)

@app.route('/')                               # home
def index():
    return render_template('index.html')

@app.route('/reports', methods=['POST'])      # reports
def reports():
    cols = ['street', 'city',  'zip', 'beds', 'baths', 'sq__ft', 'price']
    zip_code = request.form.get('zip_code', type=int)
    myData = (pd.read_csv('real-estate.csv', usecols=cols)[lambda x: x['zip'] == zip_code])
    return render_template('reports.html', zip_code=zip_code, myData=myData)

@app.route('/contact')                        # contact
def contact():
    return render_template('contact.html')
  • Line [2] contains a list of DataFrame columns to use. This list is an argument on Line [4].
  • Line [3] retrieves the Zip Code entered on the Home page (index.html) and converts it to an integer.
  • Line [4] does the following:
    • it reads in the stated CSV file.
    • It trims the DataFrame columns to the cols list on Line [2].
    • Applies a lambda to include rows where zip equals the Zip Code on Line [3].
    • It saves the output to myData.
  • Line [5] does the following:
    • Passes the HTML page name (reports.html).
    • Passes the zip_code variable (zip_code=zip_code).
    • Passes the myData DataFrame (myData=myData).
    • Returns and renders the template.

Display Results

In this section, the Reports page (reports.html) code is updated to accommodate the display of the DataFrame records.

{% extends 'base.html' %}

{% block content %}     
   <div class='container'>
      <h2>Real Estate Transactions</h2>
      <h3>{{ zip_code }}</h3>
      <br/><br/>

      <table width="600">
      <thead>
         <tr>
            {% for column in myData.columns %}
               <th>{{column}}</th>
            {% endfor %}
         </tr>
      </thead>
      <tbody>
         {% for key,value in myData.iterrows() %}
            <tr id="row-{{key}}">
               {% for v in value.values %}
                  <td>{{ v }}</td>
               {% endfor %}
            </tr>
         {% endfor %}
      </tbody>
      </table>
   </div>
{% endblock %}
  • Line [1] displays the Page Heading.
  • Line [2] displays the Zip Code retrieved from render_template().
  • Lines [3-5] does the following:
    • defines an opening HTML table tag (<table>) with a width.
    • defines an opening HTML heading tag (<thead>).
    • defines an opening HTML row tag (<tr>).
  • Lines [6-8] does the following:
    • defines the opening for loop tag using Jinja.
      • Uses Jinja to loop through myData and display the headings on a single row. One name per <th></th> tag.
    • closes the for loop using Jinja.
  • Lines [9-10] does the following:
    • defines a closing HTML row tag (</tr>).
    • defines a closing HTML header tag (</thead>).
  • Lines [11] defines an opening HTML tbody tag (<tbody>).
  • Lines [12-19] do the following:
    • uses Jinja to iterate through myData.
    • displays one record per row.
    • displays the column data per <td></td> HTML tag.
    • closes the for loop using Jinja.
  • Lines [20-21] does the following:
    • defines a closing </tbody> tag.
    • defines a closing </table> tag.

Save and run!

If the Zip Code exists in the DataFrame, the output will display as follows.

Output (snippet)

πŸ’‘ Note: To view any changes, Flask needs to be re-started. To perform this task, navigate to the command prompt and enter CTRL+C (stop), then flask run (re-start).


Summary

In this article, you learned how to:

  • Read in the Real Estate CSV file.
  • Query the results based on a Zip Code.
  • Display the results on the Reports page.

What’s Next

In Part 6 of this series, we will:

  • Validate the Zip Code.
  • Clean-Up the Data.
  • Correct the Sales Prices.
  • Format the Sales Prices.
  • Update the Navbar.