- Flask · PyPI
- Primer on Jinja Templating – Real Python
- Welcome to Flask — Flask Documentation (2.3.x) (palletsprojects.com)
- Tutorial — Flask Documentation (2.3.x) (palletsprojects.com)
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>