Flask + Vue.js : Fullstack Development
GOAL: 搭建一个基于 flask + vue.js,可以快速开发的全栈框架。具有以下特色:
- 整体的登入验证:
flask-security
- 便利的后台界面可供修改数据库:
flask-admin
- 使用
Vue.js
开发前端 UI - flask 提供 restful API, 包含 apidoc
Swagger UI
This tutorial shows how to build a system with python flask and vue.js. In the end of this article, we will have a skeleton application ready for rapid development.
Here’s the source code: github repository
This series of tutorial have 5 parts:
- Part 1 : Environment, Flask HelloWorld, Blueprint
- Part 2 : Flask config, logging, unit-testing, SQLAlchemy
- Part 3 : Restful API, Marshmallow, Swagger apidoc
- Part 4 : Flask-Admin, Flask-Security
- Part 5 : Vue.js
Prepare the Environment
先用 pyenv 建立一个虚拟环境;这样做的好处是可以有一个独立的开发环境,不会与其他专案不同的软件版本发生冲突。
First, Let’s create a virtual environment for python using pyenv
. In this way, we can isolate our project and eliminate potential package version conflicts with other projects in developer’s computer.
# make a new environment called 'fv'
pyenv virtualenv 3.6.2 fv
# enter our project folder (~/repos/flask-vue), and assign the new env to this folder.
cd ~/repos/flask-vue
pyenv local fv
# make backend folders
mkdir b2e b2e/config b2e/dodo b2e/dodo_test
Project Folder Structure :
├── f2e // frontend vue.js code, explain later
└── b2e // backend python code
├── config // python configuration
├── dodo // python flask app
└── dodo_test // python unit tests
Flask Helloworld
Install the python package: flask
pip install flask
Edit file: ./dodo/app1.py
as
from flask import Flask, jsonify
def create_app():
app = Flask(__name__, static_folder='./')
@app.route('/')
def root():
data = dict(say="hello")
return jsonify(data), 200
return app
if __name__ == '__main__':
app = create_app()
app.run()
Test the hello world example!
# bring up flask app
FLASK_DEBUG=1 python dodo/app1.py
# open browser to see result, or use curl:
curl http://localhost:5000
{
"say": "hello"
}
Introducing Flask Blueprint
Flask Blueprint 可以将不同的模块、子系统,拆分开来在不同的资料夹、文件中开发。 然后利用注册每个蓝图到 flask 主要的 app 的方式整合在一起。这样的拆分方式, 利于在中到大型的系统开发项目中,繁多的原始码仍然简洁而有结构地安排在每个文件及资料夹中。
Flask Blueprint can help us to separate modules/sub-system into different files, and later register them into our main flask-app. This feature is very useful for building medium to large scale applications with succinct and structured code files.
We will make 2 blueprints :
doggy_api
: APIs return json datadoggy_pages
: html page rendered by flask
└── b2e/
└── dodo/
├── app2.py
└── doggy/
├── api.py
├── pages.py
└── templates/
└── show.html
file ./dodo/doggy/api.py
:
from flask import Blueprint, jsonify
from flask import current_app as app
blueprint_api = Blueprint('doggy_api', __name__)
@blueprint_api.route('/list', methods=['GET'])
def get_list():
data = [{ 'name': 'dog_aaa' }, { 'name': 'dog_bbb' }]
return jsonify(data)
@blueprint_api.route('/count', methods=['GET'])
def get_count():
data = { 'count': 10 }
return jsonify(data)
file ./dodo/doggy/pages.py
:
from flask import Blueprint, render_template
blueprint_pages = Blueprint('doggy_pages', __name__, template_folder='templates')
@blueprint_pages.route('/<page_name>')
def show(page_name):
return render_template('show.html', page_name=page_name)
file ./dodo/doggy/templates/show.html
:
<html>
<head></head>
<body>
<h2>doggy - pages</h2>
<h2>You are visiting page: { { page_name } }</h2>
</body>
</html>
file ./dodo/app2.py
:
from .doggy.api import blueprint_api
from .doggy.pages import blueprint_pages
def create_app():
app = Flask(__name__, static_folder='./')
app.register_blueprint(blueprint_api, url_prefix='/doggy/api')
app.register_blueprint(blueprint_pages, url_prefix='/doggy/pages')
# ...
return app
if __name__ == '__main__':
app = create_app()
app.run()
因为程序中引用了 内部 module: doggy.api, 所以要将 dodo 资料夹视为一个 package.
Since we are referencing internal module:’doggy.api’, the folder:’dodo’ should be treated as a python ‘package’.
# declare folder:'dodo' as a package
touch ./dodo/__init__.py
# run flask app
FLASK_DEBUG=1 FLASK_APP=dodo/app2.py flask run
# test api in blueprint
curl http://localhost:5000/doggy/api/list
# visit the html page
curl http://localhost:5000/doggy/pages/abcde