在預設情況下 Flask 路由的 HTTP 方法只允許 GET
可以透過route()
裝器的methods
參數來處理不同的 HTTP 方法
from flask import request
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
return do_the_login()
else:
return show_the_login_form()
如果你有靜態檔案,例如 CSS 或是 JavaScript 檔案
雖然我只打算寫個只回 JSON 格式的純後端 API,但是因為這是 Flask 的功能還是提一下
只要在專案下建立一個叫做static
的資料夾
就可以使用「static」建立生成 URL
url_for('static', filename='style.css')
於是就會產生一個連接到專案中static/style.css
的網址
在 python 產生 HTML 並不好玩,不像 PHP
所以 Flask 自動配置了 Jinja 模板引擎,跟 Laravel 的Blade 有 87% 像
可以使用render_template()
來根據「模板名稱」和「需要的參數」渲染模板
from flask import render_template
@app.route('/hello/')
@app.route('/hello/<name>')
def hello(name=None):
return render_template('hello.html', name=name)
接著 Flask 會在主程式同階層的templates
資料夾裡面尋找模板
資料夾結構會像底下這樣
/application.py
/templates
/hello.html
而模板檔案內容會長得像底下這樣
templates/hello.html
<title>Hello from Flask</title>
{% if name %}
<h1>Hello {{ name }}!</h1>
{% else %}
<h1>Hello, World!</h1>
{% endif %}
接著啟動 Flask 服務看看畫面,的確是依照我們設定的路由規則渲染了模板
更多使用方式可以參考:Jinja 模板文件
可以在文件的:模板繼承 找到使用方法
基本上還是跟 Laravel 的 blade 很像
首先在 templates 資料夾中建立共用模板 layout.html
<!doctype html>
<html>
<head>
{% block head %}
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<title>{% block title %}{% endblock %} - My Webpage</title>
{% endblock %}
</head>
<body>
<div id="content">{% block content %}{% endblock %}</div>
<div id="footer">
{% block footer %}
© Copyright 2021 by <a href="https://tech.ray247k.com/">ray247k</a>.
{% endblock %}
</div>
</body>
</html>
再把剛剛的 hello.html 內容改成
{% extends "layout.html" %}
{% block title %}Index{% endblock %}
{% block head %}
{{ super() }}
<style type="text/css">
.important { color: #336699; }
</style>
{% endblock %}
{% block content %}
<h1>Index</h1>
<p class="important">
Welcome on my awesome homepage.
{% endblock %}
測試執行結果
在 layout.html 中定義了四個可以被子模板填充的 {% block %}
區塊,並給與區塊名稱
而子模板,也就是原本的 hello.html 中
開頭使用 {% extends %}
聲明了他是繼承於另一個模板
當使用到這個模板的時候就會先找到他父層的模板,這個宣告必須加在模板最前面!
而{{ super() }}
則是讓我們使用父模板中的內容
在 layout.html 的{% block head %}
區塊中,有加入了內容
若是在子模板中不使用{{ super() }}
宣告,則不會出現在子模板渲染的內容裡
最後就是一個蘿蔔一個坑,把子模板中相同名稱的 block 內容塞進父模板裡渲染頁面