Day 62 - Coffee & Wifi Project


Posted by pei_______ on 2022-06-16

learning from 100 Days of Code: The Complete Python Pro Bootcamp for 2022


helpful document
Flask - WTF Documentation
Flask - Bootstrap Documentation


main.py


# ---------- 00. Install ----------- #

# install flask
from flask import Flask, render_template, redirect

# install bootstrap
from flask_bootstrap import Bootstrap

# install WTF
from flask_wtf import FlaskForm
# install WTF - Field
from wtforms import StringField, SubmitField, SelectField
# install WTF - validators
from wtforms.validators import DataRequired, URL

# install csv to open csv
import csv


# ---------- 01. Set up ----------- #

app = Flask(__name__)
app.config['SECRET_KEY'] = 'it-is-ok-for-just-type-some-strings'

# set Boostrap (and also css in flask)
Bootstrap(app)

# point1. set WTF class & use new SelectField
class CafeForm(FlaskForm):
    cafe = StringField('Cafe name', validators=[DataRequired()])
    location = StringField('location_url', validators=[DataRequired(), URL()])
    opening_time = StringField('opening_time', validators=[DataRequired()])
    closing_time = StringField('closing_time', validators=[DataRequired()])
    coffee_rating = SelectField(choices=["✘", "☕", "☕☕", "☕☕☕", "☕☕☕☕", "☕☕☕☕☕"])
    wifi_rating = SelectField(choices=["✘", "💪", "💪💪", "💪💪💪", "💪💪💪💪", "💪💪💪💪💪"])
    power_rating = SelectField(choices=["✘", "🔌", "🔌🔌", "🔌🔌🔌", "🔌🔌🔌🔌", "🔌🔌🔌🔌🔌"])
    submit = SubmitField('Submit')


# ---------- 02. Build Connect ----------- #

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


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

    # point2. set form object
    form = CafeForm()

    if form.validate_on_submit():
        with open("cafe-data.csv", "a") as file:

            # point3. return data if submit is valid
            cafe = form.cafe.data
            location = form.location.data
            o_time = form.opening_time.data
            c_time = form.closing_time.data
            coffee_rating = form.coffee_rating.data
            wifi_rating = form.wifi_rating.data
            power_rating = form.power_rating.data
            file.write(f"{cafe},{location},{o_time},{c_time},"
                       f"{coffee_rating},{wifi_rating},{power_rating}\n")

        # point4. use redirect in switch to the other page
        return redirect("cafes")
    return render_template('add.html', form=form)


@app.route('/cafes')
def cafes():

    # point5. change csv to list
    with open('cafe-data.csv', newline='') as csv_file:
        csv_data = csv.reader(csv_file, delimiter=',')
        list_of_rows = []
        for row in csv_data:
            list_of_rows.append(row)
    return render_template('cafes.html', cafes=list_of_rows)


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

index.html

{% extends 'bootstrap/base.html' %}

{% block title %}Coffee and Wifi{% endblock %}

{% block styles %}
{{ super() }}
    <link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
{% endblock %}

{% block content %}
<div class="text-center jumbotron">
    <div class="container">
  <h1 class="display-4">☕️ Coffee & Wifi 💻</h1>
  <p class="lead">Want to work in a cafe but need power and wifi?</p>
  <hr class="my-4">
  <p>You've found the right place! Checkout my collection of cafes with data on power socket availability, wifi speed and coffee quality.</p>
  <a class="btn btn-warning btn-lg" href="{{ url_for('cafes') }}" role="button">Show Me!</a>
</div>
    </div>

{% endblock %}

cafes.py

{% extends 'bootstrap/base.html' %}

{% block title %}Restaurants{% endblock %}
{% block styles %}
{{ super() }}
    <link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
{% endblock %}
{% block content %}

<div class="container">
  <div class="row">
    <div class="col-sm-12">

      <h1>All Cafes</h1>

      <table class="table">

          <thead>
          {% for title in cafes[0]: %}
          <th>{{ title }}</th>
          {% endfor %}
          </thead>

          <tbody>
          {% for cafe in cafes[1:]: %}
          <tr>
              {% for info in cafe: %}
                {% if "http" in info: %}
                    <td><a href="{{ info }}">Maps Link</a></td>
                {% else: %}
                    <td>{{ info }}</td>
                {% endif %}
              {% endfor %}
          </tr>
          {% endfor %}
          </tbody>

      </table>
    </div>
  </div>
    <p><a href="{{ url_for('home') }}">Return to index page</a></p>
</div>

{% endblock %}

add.html

{% extends 'bootstrap/base.html' %}
{% import "bootstrap/wtf.html" as wtf %}

{% block title %}Add A New Cafe{% endblock %}
{% block styles %}
{{ super() }}
    <link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
{% endblock %}
{% block content %}
<div class="container">
  <div class="row">
    <div class="col-sm-12 col-md-8">

      <h1>Add a new cafe</h1>

      {{ wtf.quick_form(form, novalidate=True) }}

      <p class="space-above"><a href="{{ url_for('cafes') }}">See all cafes</a></p>

    </div>
  </div>
</div>

{% endblock %}

#Python #課堂筆記 #100 Days of Code







Related Posts

React Next.js and Material UI(MUI)

React Next.js and Material UI(MUI)

[FE302] React 基礎 - hooks 版本:再度中場休息

[FE302] React 基礎 - hooks 版本:再度中場休息

改善肩背疼痛的一些動作

改善肩背疼痛的一些動作


Comments