前几天有提到在工厂模式中,我们会用一个函式把全部 app
生起来,今天要实作的就是这个函式,一般习惯会使用 create_app
或 make_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
是未来用来放资料库结构的地方,但是我们还没到那个部分,就先留着这样就好。
接下来,我们就来看看该怎麽写吧。我们要把这个函式放在 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
,他也是一个核心的概念,之後要寄信的时候就会直接找他。Pagedown
和 Markdown
也是相同的概念。再来是刚刚弄好的 db
,我们也需要他来初始化。最後还有之前写好的设定档对照表,让我们可以根据环境来决定要用哪个设定。
接下来看到在下面我们把 LoginManager
、Mail
、Pagedown
和实体化,因为等等会用到这三个实体去初始化。
终於进入 create_app
函式本身了,当然我们需要先弄出 app
,但这次的宣告和之前的范例有些不同,多了 template_folder
和 static_folder
两个参数,应该可以猜到,他们就是用来指定 jinja 模板目录和 JS、CSS 那些档案的目录的,预设值分别是 templates
和 static
,如果不喜欢这个名字也可以自己改掉。这边会需要设定是因为我们这两个目录跟 __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
没有办法这样做,毕竟他在其他地方就定义好了。
Modular Applications with Blueprints
目录 09-01-2021 Bonjour! 接下来的 30 天里,每天一点小知识将写下我脑中盘之错...
今天要继续讲一下GraphQL(Hasura)里面的一个小功能 - Event Trigger。 会...
这个系列的 Day 19 至 Day 24 都是为了完成永丰银行数位金融 API 「丰收款」结合 W...
我本来只是想在注册页面(Signup)增加手机号码(不需简讯验证) 结果被Allauth跟djang...
Hi Da Gei Ho~ 初次见面,我是Winnie~ 我是一位刚转职六个月的菜鸟前端(前身是网页...