iT邦幫忙

2021 iThome 鐵人賽

DAY 21
0
Modern Web

Flask系列 第 21

Day 21 實作路徑結構

前言

今天我們要來開始寫路徑,也就是說在今天寫完之後我們就可以把之前藍圖的註解取消了。

main_bp

首先,我們來看看最簡單的 main_bp,裡面基本上只有一個路徑,就是首頁。

在開始之前,我們要先在 app/main/ 裡面加一個 views.py,等等路徑會寫在這裡面。

__init__.py


from flask import Blueprint

main_bp = Blueprint("main", __name__)

from . import views

views.py

from werkzeug.exceptions import HTTPException
from . import main_bp


@main_bp.route("/", methods=["GET"])
def index_page():
    pass


@main_bp.app_errorhandler(401)
def handler_401(e):
    pass


@main_bp.app_errorhandler(HTTPException)
def handler(e):
    pass

這邊的 __init__.py 跟很久以前寫的有一點點不太一樣,多加了一行 from . import views,這樣他才會被好好 register 進 app

接下來看到 views.py,要特別注意,我們是用 main_bp 來註冊路徑,而不是 app,所以我們也需要從剛剛的 __init__.py 裡面引入 main_bp。裡面有一個 index_page,我們不會拿它來幹嘛,就是一個放好看的頁面而已,也不會有甚麼表單,所以 methods 就只有最簡單的 GET

再來是兩個 app_error_handler,他們就是用來處理錯誤的。第一個是處理 401 錯誤,也就是未驗證,之前在寫測試的時候有說過我們要讓他直接重新導向至登入頁面。剩下的錯誤就交給第二個,我們用 HTTPException 來接收,我們之後會寫一個模板給他,讓不管什麼錯誤都可以回傳模板。他們兩個都有一個 e 作為參數,他就是那個錯誤本身,我們之後會在第二個 handler 用到他。

user_bp

接著要看到 user_bp,這裡會有一堆跟使用者有關的路徑,像是登入登出、貼文、使用者設定等等。跟剛剛一樣,我們也需要一個 views.py,而這次路徑比較多,所以也可以把他拆開來,但要記得,在 __init__.py 要把每一個路徑檔案都引入。

__init__.py

from flask import Blueprint

user_bp = Blueprint("user", __name__)

from . import views

views.py

from flask_login import login_required
from . import user_bp

@user_bp.route("/login", methods=["GET", "POST"])
def login_page():
    pass

@user_bp.route("/logout", methods=["GET"])
def logout_page():
    pass

@user_bp.route("/register", methods=["GET", "POST"])
def register_page():
    pass

@user_bp.route("/setting", methods=["GET", "POST"])
@login_required
def user_setting_page():
    pass

@user_bp.route("/post/add", methods=["GET", "POST"])
@login_required
def add_post_page():
    pass

@user_bp.route("/post/edit/<int:post_id>", methods=["GET", "POST"])
@login_required
def edit_post_page(post_id):
    pass

@user_bp.route("/post/delete/<int:post_id>", methods=["GET"])
@login_required
def delete_post_page(post_id):
    pass

@user_bp.route("/dashboard", methods=["GET", "POST"])
@login_required
def dashboard_page():
    pass

@user_bp.route("/comments", methods=["GET"])
@login_required
def comments_dashboard_page():
    pass

@user_bp.route("/posts", methods=["GET"])
@login_required
def all_posts_page():
    pass

@user_bp.route("/post/<int:post_id>", methods=["GET", "POST"])
@login_required
def view_post_page(post_id):
    pass

@user_bp.route("/@<username>/posts", methods=["GET"])
@login_required
def user_posts_page(username):
    pass

這邊路徑很多,我們一個一個來解釋。但開始講路徑之前,我們先來看看最前面的 login_required。顧名思義,他就是要求使用者要先登入才能進入這個網頁,如果沒登入的話就會丟出 401,那根據剛剛 main_bpapp_error_handler,他會重新導向到登入頁面。但現在他還不能使用,因為我們還沒有完成 FLask-Login 的一些要求,所以現在他會噴錯誤。

接下來就來看看各個路徑要幹嘛吧,我們會用路徑來表示。

  • /login 當然就是登入頁面,我們需要有 GET 和 POST,這樣才能送表單出去。
  • /logout 是登出頁面,戳一下系統就會把使用者登出。
  • /register 是註冊頁面,跟登入頁面同理,也需要 GET 和 POST。
  • /setting 是使用者設定頁面,一樣需要提交表單,所以 GET 和 POST 都要。
  • 來到了貼文的部分,/post/add 是新增貼文的頁面,也就是之前說要放 pagedown 表單的地方。這邊當然需要做 login_required,除非要允許匿名發文。
  • /post/edit/<int:post_id> 是編輯貼文的地方,我們會跟新增貼文用一樣的表單。但這邊需要 post_id,這樣才知道現在在修改哪一篇文章。
  • post/delete/<int:post_id> 會用來刪除貼文,就像登出一樣,戳一下文章就被刪掉了。
  • /dashboard 是使用者看自己全部貼文的地方,因為有篩選器的表單,所以這裡也需要 POST。
  • /comments 是使用者看自己全部留言的地方,但我們在這裡沒有做篩選器,所以就不需要 POST 了,
  • /posts 是看整個系統全部人文章的地方,也可以不要 login_required,這樣匿名使用者也可以看到文章。
  • /post/<int:post_id> 則是看某一篇文章,後面的 post_id 會告訴系統要抓哪一篇文章出來。他也需要 POST,因為留言的表單會放在這裡。
  • /@<username>/posts 是一個額外的東西,可以把該使用者的貼文全部抓出來。

admin_bp

最後我們來到了 admin_bp,比起剛剛,這裡的路徑就少了不少。這邊有一些不太一樣的路徑,它們是只接收 POST、DELETE 等等 method,所以使用者不會直接去戳到他,而是要靠 JS 之類的東西來戳。

__init__.py

from flask import Blueprint

admin_bp = Blueprint("admin", __name__)

from . import views

views.py

from . import admin_bp


@admin_bp.route("/admin_dashboard/posts", methods=["GET", "POST"])
def admin_dashboard_posts_page():
    pass

@admin_bp.route("/admin_dashboard/comments", methods=["GET", "POST"])
def admin_dashboard_comments_page():
    pass

@admin_bp.route("/manage_user", methods=["GET", "POST"])
def manage_user_page():
    pass

@admin_bp.route("/admin_dashboard_posts_backend", methods=["DELETE"])
def admin_dashboard_posts_backend():
    pass

@admin_bp.route("/admin_dashboard_comments_backend", methods=["DELETE"])
def admin_dashboard_comments_backend():
    pass

@admin_bp.route("/manage_user_backend", methods=["PATCH", "DELETE"])
def manage_user_backend():
    pass

這裡分成前面三個和後面三個,分別是給使用者用的和給 JS 戳的,所以後者我會等到真的在寫的時候再詳細講,然後他們也是一一對應的。接下來就一個一個看看他們。

  • /admin_dashboard/posts 是給管理員看全部貼文的地方,同時也會允許管理員直接刪除貼文,請求會由 JS 送到 admin_dashboard_posts_backend。他需要有 POST,因為有篩選器要用。
  • /admin_dashboard/comments 跟剛剛接近,只是是看留言的地方。也需要 POST,因為有篩選器。
  • /manage_user 是管理使用者的頁面,可以看到所有使用者,然後也可以刪除、更新 (manage_user_backend) 及新增 (表單)。

後記

在這邊全部結束之後,我們就可以把之前 app/__init__.py 那些對於藍圖的註解移除,然後使用 flask shell 來看看 app.url_map 有沒有一大堆東西,如果有那基本上就是成功了。


上一篇
Day 20 實作表單 (3)
下一篇
Day 22 實作 main_bp
系列文
Flask30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言