开始专案前需要先对 Flask 设定一下,让它能够开发的更顺手(又是一段超短的开头)。
刚刚在启动 server 时使用到了 set
这个指令,set
其实是设定环境变数的指令,flask run
这行是使用了 flask-cli,让 flask 自动去抓环境变数来设定并执行。不过如果现在有一堆东西要设定,一行一行慢慢写入也太花时间,而且有时候不小心忘记设定过了什麽又要在茫茫大海中寻找,非常花时间。所以现在就要来讲一下如何设定并且开始一个 flask 时有什麽要设定的。
flask 中可设定的值大概有这些 Builtin Configuration Value
首先,让 flask 运行起来的方式有两种,透过 flask-cli 或透过 python 来启动。
先来说透过 flask-cli 启动要如何设定:
flask-cli 可以抓环境变数来载入设定後执行,但是一行一行写入不方便管理,那怎麽办呢?
你可以透过 .env
档或是 .flaskenv
档(这两个档案的写法都跟 Day 09 的 .env
档一样,啊记得放在专案根目录)来统一管理设定,并且 flask-cli 会自动将 这两个档案载入到设定後才执行。
而 flask-cli 下指令的时候也可以加上参数。那这三个同时下不同指令的时候会发生什麽事呢(正常不会这样做,我只是举例而已)?
由於载入的顺序大概是这样 .flaskenv
=> .env
=> CLI-settings(J个是尛?flask run
这个东西,flask run --help
就可以看到怎麽使用了。再说一次,用虚拟环境的要进入虚拟环境喔),所以在後面载入的 .env
会覆盖掉 .flaskenv
的值;更後面的 CLI-settings 又会覆盖掉 .env
的值,大概就这样。
.env
、.flaskenv
这两个档案较适用於不适合公开的设定,例如之後会讲到的 SECRET_KEY
,那麽透过 python 启动呢?
python 启动其实就只是 python app.py
这样而已。要执行前必须把刚刚注解的那两行加进来,不然不会执行。
那这样做有什麽差别呢?
这个方式可以用很多其他的方式来载入设定後再执行(不过这边的方法都在 flask-cli 启动时都是在执行後才会载入,这样就没有意义了),甚至做到只改一行就改变所有设定;不过 .env
跟 .flaskenv
就不行了(虽然 .env
可以另外透过 python-dotnev 这个模组的 load_dotenv()
这个方式额外载入)。
到底又有什麽方式可以载入设定呢?先说比较简单的:
这应该是最简单的,因为 Flask 的 config 其实就是一个 dict (字典,Day 03 有讲到),要改写这个 dict 就直接抓它的 key 改 value 就行了。像这样:
from flask import Flask
app = Flask(__name__)
app.config["ENV"] = "development"
app.config["DEBUG"] = True
@ app.route("/")
def index():
return "Hello World"
if __name__ == "__main__":
app.run()
再把它 run 起来
# 再提醒一次,有用虚拟环境的要进去虚拟环境
$ pipenv shell
$ python app.py
应该可以看到 Environment 变成 development 以及 Debug 变成 on 了!
这个方式跟第一个方式其实差不多,都是基於 dict 去操作的,但是不用一个一个改,只要写好一次 update 就可以了。大概像这样:
from flask import Flask
CONFIGS = {
"ENV": "development",
"DEBUG": True
}
app = Flask(__name__)
app.config.update(CONFIGS)
@ app.route("/")
def index():
return "Hello World"
if __name__ == "__main__":
app.run()
# 进入虚拟环境
$ pipenv shell
$ python app.py
因为我都让它们做同样事情,结果不会不一样(有不一样就是你弄错了),所以我就懒得放涂了。
第三个方式跟第二个差不多,不过不再基於 dict 去操作,使用的是 flask 提供的方式。像这样:
from flask import Flask
CONFIGS = {
"ENV": "development",
"DEBUG": True
}
app = Flask(__name__)
app.config.from_mapping(CONFIGS)
@ app.route("/")
def index():
return "Hello World"
if __name__ == "__main__":
app.run()
# 进入虚拟环境
$ pipenv shell
$ python app.py
对,结果应该又是一样的。
这个方式开始就有点不同了,是引入一个档案(不需要 import,直接输入档名),需要新增一个档案。结构长这样:
ithome/
├── app.py
├── configs.py
├── Pipfile
└── Pipfile.lock
configs.py
ENV = 'development'
DEBUG = True
app.py
from flask import Flask
app = Flask(__name__)
app.config.from_pyfile('configs.py')
@ app.route("/")
def index():
return "Hello World"
if __name__ == "__main__":
app.run()
# 进入虚拟环境
$ pipenv shell
$ python app.py
对啦,结果又双是一样的。
这个方式跟前一个差不多,但是需要新增环境变数,然後从环境变数中抓到该去哪里找设定档。像这样:
ithome/
├── app.py
├── configs.py
├── Pipfile
└── Pipfile.lock
configs.py
ENV = 'development'
DEBUG = True
app.py
from flask import Flask
app = Flask(__name__)
app.config.from_envvar('FLASK_SETTINGS')
@ app.route("/")
def index():
return "Hello World"
if __name__ == "__main__":
app.run()
# 进入虚拟环境
$ pipenv shell
# 设定环境变数
$ set FLASK_SETTINGS=./configs.py
# 执行
$ python app.py
对啦,结果又双叒是一样的。
这个方式是我比较喜欢的,因为可以同时存放多种设定,例如开发环境设定、部署环境设定等,不用有一堆设定档,也不需要使用到环境变数,也支援多种方式。像这样:
ithome/
├── app.py
├── configs.py
├── Pipfile
└── Pipfile.lock
导入後套用设定
configs.py
ENV = 'development'
DEBUG = True
app.py
from flask import Flask
import configs as CONFIGS
app = Flask(__name__)
app.config.from_object(CONFIGS)
@ app.route("/")
def index():
return "Hello World"
if __name__ == "__main__":
app.run()
# 进入虚拟环境
$ pipenv shell
$ python app.py
直接呼叫模组名称
configs.py
ENV = 'development'
DEBUG = True
app.py
from flask import Flask
app = Flask(__name__)
app.config.from_object("configs")
@ app.route("/")
def index():
return "Hello World"
if __name__ == "__main__":
app.run()
# 进入虚拟环境
$ pipenv shell
$ python app.py
物件化多设定档
configs.py
class Config:
TESTING = False
class ProductionConfig(Config):
FLASK_ENV = 'production'
DEBUG = False
class DevelopmentConfig(Config):
ENV = 'development'
DEBUG = True
class TestingConfig(Config):
TESTING = True
app.py
from flask import Flask
import configs
app = Flask(__name__)
app.config.from_object(configs.DevelopmentConfig)
@ app.route("/")
def index():
return "Hello World"
if __name__ == "__main__":
app.run()
# 进入虚拟环境
$ pipenv shell
$ python app.py
对啦,结果又双叒叕是一样的。
最後,app.run()
也是可以加参数的,参考 run()
那麽就大概这样,本来想说设定只有一点点的,可是没想到也这麽多。
大家掰~掰~
>>: Python - PySparkPracticeQuestions - PySpark 练习题参考笔记
第一次压线发文耶,今天真的有点忙,到现在才发文。Menu就是功能表的表单,通常都会在介面的最上面,是...
Day 29 - 客户说:我是个人户,但是有个理念一直很想要做看看,可以帮我网站报价吗,概念是这样....
大家以为前几天介绍完产品从无到有的过程,就已经完成一个完整的软件开发流程了吗?如果是的话那你就大错特...
喵喵喵喵喵喵喵喵!!!终於写完 30 天的文章了,这 30 天中,我们从云端的概念开始,进入了 Go...
Day03 - 纯 Html 复杂型别 object 复杂型别定义 复杂型别我拆成三篇 object...