iT邦幫忙

2021 iThome 鐵人賽

DAY 11
0
Modern Web

Flask系列 第 11

Day 11 實作 create_app

  • 分享至 

  • xImage
  •  

前言

前幾天有提到在工廠模式中,我們會用一個函式把全部 app 生起來,今天要實作的就是這個函式,一般習慣會使用 create_appmake_app,我們選擇使用前者。

前置作業

如同昨天所說,我們在 create_app 裡面會需要初始化一些東西,而這其中包括了資料庫。而我們會另外開一個 app/database 來處理資料庫的事務,初始化會用到的 db 也不例外,所以我們先來處理一下資料庫的相關作業。以下程式碼都會放在 app/database 中。

__init__.py

from .models import db

models.py

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

很明顯地,app/database 也是一個 package。我們在 models.py 裡面宣告了 db 這個變數,也就是等等我們需要初始化 app 的幫手。接著在 __init__.py 裡面把 db 引入,這樣等等就可以讓別人引入。這個 models.py 是未來用來放資料庫結構的地方,但是我們還沒到那個部分,就先留著這樣就好。

create_app

接下來,我們就來看看該怎麼寫吧。我們要把這個函式放在 app/__init__.py 裡面。

from flask import Flask
from flask_login import LoginManager
from flask_mail import Mail
from flask_pagedown import PageDown
from flaskext.markdown import Markdown
from .database import db
from .config import configs

login_manager = LoginManager()
mail = Mail()
pagedown = PageDown()


def create_app(env):
    app = Flask(__name__, template_folder="../templates", static_folder="../static")
    app.config.from_object(configs[env])

    login_manager.init_app(app)
    db.init_app(app)
    mail.init_app(app)
    pagedown.init_app(app)
    Markdown(app)

    # Blueprint
    from .main import main_bp

    app.register_blueprint(main_bp)

    from .user import user_bp

    app.register_blueprint(user_bp)

    from .admin import admin_bp

    app.register_blueprint(admin_bp)

    return app

一開始要先注意一下最後面 # Blueprint 後面的程式碼,他們目前都不存在,在未來我們會實做到。跟之前說過的一樣,基本上他們就是一堆路徑,然後分門別類放好,讓我們好管理。我們會用 register_blueprint 這個函式把整個藍圖加入 app 裡面。我們也可以使用 url_prefix 這個參數來設定這個藍圖的母路徑,例如說,我們設定 url_prefix="/auth",那在這個藍圖裡面的路徑前面都會被冠上 /auth,如果他用的路徑是 /login,那 register 過後就會變成 /auth/login。但我們在此專案不會用到,所以先略過。

接著看到最上面的一堆引入,我們引入了 LoginManager,他是 Flask-Login 的核心。也引入了 Mail,他也是一個核心的概念,之後要寄信的時候就會直接找他。PagedownMarkdown 也是相同的概念。再來是剛剛弄好的 db,我們也需要他來初始化。最後還有之前寫好的設定檔對照表,讓我們可以根據環境來決定要用哪個設定。

接下來看到在下面我們把 LoginManagerMailPagedown 和實體化,因為等等會用到這三個實體去初始化。

終於進入 create_app 函式本身了,當然我們需要先弄出 app,但這次的宣告和之前的範例有些不同,多了 template_folderstatic_folder 兩個參數,應該可以猜到,他們就是用來指定 jinja 模板目錄和 JS、CSS 那些檔案的目錄的,預設值分別是 templatesstatic,如果不喜歡這個名字也可以自己改掉。這邊會需要設定是因為我們這兩個目錄跟 __init__.py 不是同一層目錄,需要往上一層。這個 create_app 接受了 env 這個參數,接下來我們就要用他來匯入之前寫的設定檔。flask 很好心地有一個函是可以讓我們直接從物件匯入,也就是此處的 app.config.from_object,這樣一來,我們就可以抓到之前寫的設定檔了。

最後是初始化的部分,我們需要把五個東西都初始化,這樣才能在往後的開發中使用。要初始化的方法是使用他們的 init_app 函式,並以 app 作為參數。但 Markdown 比較特別,他沒有 init_app 這個函式,所以要像 db 那樣子做,而其他三個其實也可以不要先實體化變成 login_manager,然後在 init_app 的位置初始化,像是 login_manager=LoginManager(app)。但當然 db 沒有辦法這樣做,畢竟他在其他地方就定義好了。

References

Modular Applications with Blueprints


上一篇
Day 10 實作基本檔案
下一篇
Day 12 實作資料庫
系列文
Flask30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言