1. 程式人生 > >遇見Flask-Script

遇見Flask-Script

Flask-Script是Flask的命令列擴充套件包,使用它可以通過命令列的形式操作Flask專案, 例如,可通過命令啟動一個發版本的伺服器,設定資料庫和定時任務等。

類似Django的manage.py提供的命令,不同的是使用flask-script可以自定義更多的命令。

Install flask-script

一般在虛擬環境中安裝

(flask_env) [email protected]:~/PycharmProjects/flask_one$ pip install flask-script
Collecting flask-script
  Downloading https://files.pythonhosted.org/packages/00/a4/cd587b2b19f043b65bf33ceda2f6e4e6cdbd0ce18d01a52b9559781b1da6/Flask-Script-2.0.6.tar.gz (43kB)
    100% |████████████████████████████████| 51kB 229kB/s 
Requirement already satisfied: Flask in /home/mark/.virtualenvs/flask_env/lib/python3.6/site-packages (from flask-script) (1.0.2)
Requirement already satisfied: Werkzeug>=0.14 in /home/mark/.virtualenvs/flask_env/lib/python3.6/site-packages (from Flask->flask-script) (0.14.1)
Requirement already satisfied: itsdangerous>=0.24 in /home/mark/.virtualenvs/flask_env/lib/python3.6/site-packages (from Flask->flask-script) (1.1.0)
Requirement already satisfied: click>=5.1 in /home/mark/.virtualenvs/flask_env/lib/python3.6/site-packages (from Flask->flask-script) (7.0)
Requirement already satisfied: Jinja2>=2.10 in /home/mark/.virtualenvs/flask_env/lib/python3.6/site-packages (from Flask->flask-script) (2.10)
Requirement already satisfied: MarkupSafe>=0.23 in /home/mark/.virtualenvs/flask_env/lib/python3.6/site-packages (from Jinja2>=2.10->Flask->flask-script) (1.1.0)
Building wheels for collected packages: flask-script
  Running setup.py bdist_wheel for flask-script ... done
  Stored in directory: /home/mark/.cache/pip/wheels/1c/17/70/4598e6dba4bec58c1b59552c6409272aea31978ab8159f11a1
Successfully built flask-script
Installing collected packages: flask-script
Successfully installed flask-script-2.0.6
(flask_env) 
[email protected]
:~/PycharmProjects/flask_one$

使用flask-script

安裝好了,不會用,怎麼辦?

在pycharm中點flask_script想進去看看,結果只進入了__init__.py中,看到如下內容:

class Manager(object):
    """
    Controller class for handling a set of commands.

    Typical usage::

        class Print(Command):

            def run(self):
                print "hello"

        app = Flask(__name__)

        manager = Manager(app)
        manager.add_command("print", Print())

        if __name__ == "__main__":
            manager.run()

    On command line::

        python manage.py print
        > hello

    :param app: Flask instance, or callable returning a Flask instance.
    :param with_default_commands: load commands **runserver** and **shell**
                                  by default.
    :param disable_argcomplete: disable automatic loading of argcomplete.

    """

使用方式一

匯入flask_script中的Manager,Command

自定義的命令需要在Command的子類中重寫run方法,在此方法中定義命令需要做什麼事

例項化Manager(可以接收一個Flask物件作為引數),呼叫Manager物件的add_command('命令', 自定義命令類例項)

from flask_script import Manager, Command
from app import app  # Flask物件


class TestCommand(Command):
    """
    測試命令
    """

    def run(self):  # 重寫Command的run方法
        # 使用命令在控制檯輸出資訊
        print("server run on xxx:80...")


manager = Manager(app) # 將flask_script與Flask聯絡起來
manager.add_command('test', TestCommand())

if __name__ == '__main__':
    manager.run()

在manage.py中執行manage.run()可以檢視這個manage中包含的命令詳情

/home/mark/.virtualenvs/flask_env/bin/python3.6 /home/mark/PycharmProjects/flask_one/manage.py
usage: manage.py [-?] {test,shell,runserver} ...

positional arguments:
  {test,shell,runserver}
    test                測試命令
    shell               Runs a Python shell inside Flask application context.
    runserver           Runs the Flask development server i.e. app.run()

optional arguments:
  -?, --help            show this help message and exit

Process finished with exit code 2

在命令列執行python manage.py test

(flask_env) [email protected]:~/PycharmProjects/flask_one$ python manage.py test
server run on xxx:80...

使用方式二

匯入flask_script中的Manager,例項化之後使用@manager.command裝飾器裝飾一個函式,這樣,這個函式名就成為一個命令,函式中的程式碼會在執行這個命令後執行。

from flask_script import Manager
from app import app

manager = Manager(app)

@manager.command
def music():
    """
    小妞,給爺唱一個
    """
    print("客官不可以,不可以摸我那裡....")


if __name__ == '__main__':
    manager.run()

使用manager.run()檢視

/home/mark/PycharmProjects/flask_one/manage.py
usage: manage.py [-?] {music,shell,runserver} ...

positional arguments:
  {music,shell,runserver}
    music               小妞,給爺唱一個
    shell               Runs a Python shell inside Flask application context.
    runserver           Runs the Flask development server i.e. app.run()

在命令列執行python manage.py music

(flask_env) [email protected]:~/PycharmProjects/flask_one$ python manage.py music
客官不可以,不可以摸我那裡....

使用方式三

將命令定義在其他模組中,再引入到manage.py,將manage.py作為主命令模組。

from flask_script import Manager

# 不作為主命令模組,也就是說命令列是python manage.py xxx..
# 使用manage.py 而不是當前模組,這裡的Manager()就不用傳如Flask物件了
db_manager = Manager()

@db_manager.command
def migrate():
    """
    資料遷移命令
    """
    print("執行資料遷移...")

在manage.py中的引入方式:manger.add_command('prefix',manager物件)

from flask_script import Manager
from app import app
from db_manager import db_manager

manager = Manager(app)

# db是字首 執行命令方式 python manage.py db migrate
manager.add_command('db', db_manager)

if __name__ == '__main__':
    manager.run()

執行結果:

(flask_env) [email protected]:~/PycharmProjects/flask_one$ python manage.py db migrate
執行資料遷移...

其他使用方式

可以使用manger.option()裝飾器

命令函式可以接收引數

彈出確認操作:

@db_manager.command
def drop_data():
    if prompt_bool("你真的要刪除這些資料嗎?後果自負哦..\t\n"
                   "輸入y刪除,n取消"):
        print('資料已刪除...')
    else:
        print("就知道你不敢")
----------------------------------------
(flask_env) [email protected]:~/PycharmProjects/flask_one$ python manage.py  db drop_data
你真的要刪除這些資料嗎?後果自負哦..    
輸入y刪除,n取消 [n]: n
就知道你不敢
(flask_env) [email protected]:~/PycharmProjects/flask_one$ 

最後

更詳細的資料在官方文件。