flask-session

การอัพโหลดไฟล์ จำเป็นต้องมีการกำหนดค่า SECRET_KEY ไม่งั้นจะ error ว่า RuntimeError: The session is unavailable because no secret key was set. Set the secret_key on the application to something unique and secret.

# save this as app.py

from flask import Flask
from flask import session
import os

app = Flask(__name__)

app.config.update(SECRET_KEY=os.urandom(24))
app.config.from_object(__name__)

@app.route("/")
def hello():
    return "Hello, World!"

if __name__ == "__main__":
    with app.test_request_context("/"):
        session["key"] = "value"

Flask

Installing

$ pip install -U Flask

A Simple Example

# save this as app.py

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello, World!"

or

# app.py

from flask import Flask

app = Flask(__name__)

@app.route("/")
def home():
    return "Hello, World!"

if __name__ == "__main__":
    app.run(debug=True)
$ flask run
  * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Add a Base Template

{# templates/base.html #}

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>{{ title }}</title>
</head>

<body>
  <h1>Welcome to {{ title }}!</h1>
</body>
</html>
# app.py

from flask import Flask
from flask import  render_template

app = Flask(__name__)

@app.route("/")
def home():
    return render_template("base.html", title="Jinja and Flask")

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

Add Another Page

{# templates/results.html #}

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>{{ title }}</title>
</head>

<body>
  <h1>{{ test_name }} {{ title }}</h1>
  <ul>
  {% for student in students %}
    <li>
      {% if student.score > 80 %}🙂{% else %}🙁{% endif %}
      <em>{{ student.name }}:</em> {{ student.score }}/{{ max_score }}
    </li>
  {% endfor %}
  </ul>
</body>
</html>
# app.py

from flask import Flask
from flask import  render_template

app = Flask(__name__)

@app.route("/")
def home():
    return render_template("base.html", title="Jinja and Flask")

max_score = 100
test_name = "Python Challenge"
students = [
    {"name": "Sandrine",  "score": 100},
    {"name": "Gergeley", "score": 87},
    {"name": "Frieda", "score": 92},
    {"name": "Fritz", "score": 40},
    {"name": "Sirius", "score": 75},
]

@app.route("/results")
def results():
    context = {
        "title": "Results",
        "students": students,
        "test_name": test_name,
        "max_score": max_score,
    }
    return render_template("results.html", **context)

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

Nest Your Templates

Adjust Your Base Template

{# templates/base.html #}

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>{% block title %}{{ title }}{% endblock title %}</title>
</head>

<body>
  {% block content %}
    <h1>Welcome to {{ title }}!</h1>
  {% endblock content %}
</body>
</html>

Extend Child Templates

{# templates/results.html #}

{% extends "base.html" %}

{% block content %}
<h1>{{ test_name }} {{ title }}</h1>
<ul>
{% for student in students %}
  <li>
    {% if student.score > 80 %}🙂{% else %}🙁{% endif %}
    <em>{{ student.name }}:</em> {{ student.score }}/{{ max_score }}
  </li>
{% endfor %}
</ul>
{% endblock content %}

Include a Navigation Menu

{# templates/_navigation.html #}

<nav>
{% for menu_item in ["home", "results"] %}
  <a href="{{ url_for(menu_item) }}">{{ menu_item }}</a>
{% endfor %}
</nav>
{# templates/base.html #}

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>{% block title %}{{ title }}{% endblock title %}</title>
</head>

<body>
  <header>
    {% include "_navigation.html" %}
  </header>
  {% block content %}
    <h1>Welcome to {{ title }}!</h1>
  {% endblock content %}
</body>
</html>

Apply Filters

Adjust Your Menu Items

แสดง link เป็น ตัวพิมพ์ใหญ่ด้วย filter upper

{# templates/_navigation.html #}

<nav>
{% for menu_item in ["home", "results"] %}
  <a href="{{ url_for(menu_item) }}">{{ menu_item|upper }}</a>
{% endfor %}
</nav>

Sort Your Results List

เรียกตาม name ด้วย filter sort

{# templates/results.html #}

{% extends "base.html" %}

{% block content %}
<h1>{{ test_name }} {{ title }}</h1>
<ul>
{% for student in students|sort(attribute="name") %}
  <li>
    {% if student.score > 80 %}🙂{% else %}🙁{% endif %}
    <em>{{ student.name }}:</em> {{ student.score }}/{{ max_score }}
  </li>
{% endfor %}
</ul>
{% endblock content %}

You used Jinja’s sort filter to sort the results of your students by their names. If you had students with the same name, then you could chain the filters:

{% for student in students|sort(attribute="score", reverse=true)
  |sort(attribute="name") %}

  {# ... #}

{% endfor %}

Include Macros

Implement a Dark Mode

{# templates/macros.html #}

{% macro light_or_dark_mode(element) %}
  {% if request.args.get('mode') == "dark" %}
    <a href="{{ request.path }}">Switch to Light Mode</a>
    <style>
      {{ element }} {
        background-color: #212F3C;
        color: #FFFFF0;
      }
      {{ element }} a {
        color: #00BFFF !important;
      }
    </style>
  {% else %}
    <a href="{{ request.path }}?mode=dark">Switch to Dark Mode</a>
  {% endif %}
{% endmacro %}
{# templates/base.html #}

{% import "macros.html" as macros %}

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>{% block title %}{{ title }}{% endblock title %}</title>
</head>

<body>
  <header>
    {% include "_navigation.html" %}
  </header>
  {% block content %}
    <h1>Welcome to {{ title }}!</h1>
  {% endblock content %}
  <footer>
    {{ macros.light_or_dark_mode("body") }}
  </footer>
</body>
</html>

Highlight Your Best Student

{# templates/results.html #}

{% extends "base.html" %}

{% block content %}
<h1>{{ test_name }} {{ title }}</h1>
<ul>
{% for student in students|sort(attribute="name") %}
  <li>
    {{ macros.add_badge(student, students) }}
    <em>{{ student.name }}:</em> {{ student.score }}/{{ max_score }}
  </li>
{% endfor %}
</ul>
{% endblock content %}
{# templates/macros.html #}

{% macro light_or_dark_mode(element) %}
  {% if request.args.get('mode') == "dark" %}
    <a href="{{ request.path }}">Switch to Light Mode</a>
    <style>
      {{ element }} {
        background-color: #212F3C;
        color: #FFFFF0;
      }
      {{ element }} a {
        color: #00BFFF !important;
      }
    </style>
  {% else %}
    <a href="{{ request.path }}?mode=dark">Switch to Dark Mode</a>
  {% endif %}
{% endmacro %}

{% macro add_badge(student, students) %}
  {% set high_score = students|map(attribute="score")|max %}

  {% if student.score == high_score %}
    ⭐️
  {% elif student.score > 80 %}
    🙂
  {% else %}
    🙁
  {% endif %}
{% endmacro %}

Mark the Current Page

{# templates/macros.html #}

{# ... #}

{% macro nav_link(menu_item) %}
  {% set mode = "?mode=dark" if request.args.get("mode") == "dark" else "" %}
  <a href="{{ url_for(menu_item) }}{{ mode }}">{{ menu_item|upper }}</a>
  {% if request.endpoint == menu_item %}
    ←
  {% endif %}
{% endmacro %}
{# templates/_navigation.html #}

<nav>
{% for menu_item in ["home", "results"] %}
  {{ macros.nav_link(menu_item) }}
{% endfor %}
</nav>