浅谈Flask目录结构以及与Vue.js整合注意事项

没用Flask之前,我对Flask的只有一个概念,那就是**Micro,官网对其的解释是这样的:Micro并不意味着你的整个Web应用程序必须只有单个Python文件(尽管可以),也不意味着Flask缺少功能。微框架中的Micro**意味着Flask旨在使核心保持简单但可扩展。Flask不会为你做出很多决定,例如使用什么数据库,而且它所做的决定(例如使用哪种模板引擎)很容易更改。其他一切都由你决定,因此Flask可以满足你的所有需求,而无所不包。

1. 前言

由于工作性质,要求写的小web应用都要涉及一些底层,不如串口通信,或者GPIO调用。而串口这种东西不像数据库连接一样,开几个都可以,也不能开了之后关然后再开(效率比数据库连接差多了)。所以最好写个全局的,开了一次就不用关了,代码量也不多,哪个简单用哪个,我就想到了用Flask。例如一个最小的应用就可以这么简单的写:

1
2
3
4
5
6
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
return 'Hello, World!'

单个Python文件就好办了,然后打开串口,在路由中引用串口实例加入一些操作,就是个能用的小型Web应用了。

2. 目录结构安排一下

即使一个项目再小也要有个规则安排,总不能真的单文件走天下。
V2EX上有篇文章探讨了Flask的目录结构,我看了上面的每个链接,果然**Flask 其实很灵活,怎样都行,怎么舒服怎么来**这句话很对。

我从一些教程或者github中综合了下,整理下我会采用的结构目录,旨在简单明了。

单模块目录结构

当项目代码量少于几百行的时候我们可以采用单模块的目录结构,也就是把所有的代码都写在app.py里,然后把一些配置(比如我上面例子中的串口位置,波特率啥的)写到config.py里,比如这样:

1
2
3
4
5
app.py
config.py
requirements.txt
static/
templates/

包目录结构

对于包目录结构我们可以按照官网推荐的来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/home/user/Projects/flask-tutorial
├── flaskr/
│ ├── __init__.py
│ ├── db.py
│ ├── schema.sql
│ ├── auth.py
│ ├── blog.py
│ ├── templates/
│ │ ├── base.html
│ │ ├── auth/
│ │ │ ├── login.html
│ │ │ └── register.html
│ │ └── blog/
│ │ ├── create.html
│ │ ├── index.html
│ │ └── update.html
│ └── static/
│ └── style.css
├── tests/
│ ├── conftest.py
│ ├── data.sql
│ ├── test_factory.py
│ ├── test_db.py
│ ├── test_auth.py
│ └── test_blog.py
├── venv/
├── setup.py
└── MANIFEST.in

看似文件很多,但是基本的骨架还是像下面这样:

1
2
3
4
5
6
7
8
9
10
11
12
config.py
requirements.txt
run.py
instance/
config.py
yourapp/
__init__.py
views.py
models.py
forms.py
static/
templates/

然后我们可以在这上面进行很多衍生,加入蓝图等东西。

更完整的目录结构

更完善的目录结构我们可以加入dockermakefile等,我们可以参考有名的cookiecutter项目模板,很全面,考虑很周到,但是在自己的开发过程中用不太到,仅供参考。

3. Flask与Vue.js整合问题

采用前后端分离开发的时候,需要整合前端vue的包,我们可以在实例化app的时候这么做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

from flask import Flask, render_template, jsonify

# Set up automatic serving of static Vue & frontend files and template folder for index.html.
app = Flask(__name__, static_folder='./dist/static', template_folder='./dist')


# Add your routes here:
@app.route('/api/posts')
def blog_posts():
return jsonify([])


# Make a "catch all route" so all requests match our index.html file. This lets us use the new history APIs in the browser.
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def index(path):
return render_template('index.html')

Vue这边也要设置,平时前后端分离开发,都是用axios到我开发的机器上拿数据,还会遇到跨域问题,但是整合的时候Vue这边打包前填什么服务器ip呢,我要是部署到别的机器ip肯定会变,ip肯定会变,总不能一个ip打一个不同的包。所以说我们需要在vue.config.js中这么配置:

1
2
3
4
5
6
module.exports = {
assetsDir: 'static', // For simple configuration of static files in Flask (the "static_folder='client/dist/static'" part in app.py)
devServer: {
proxy: 'http://localhost:5000' // So that the client dev server can access your Flask routes
}
};

这样就OK了,打一个包后续都能用了

4. 总结

对于Flask目录结构真的是仁者见仁,智者见智,怎么舒服怎么来,但是对于刚开始用的人来说不要一开始就用人家的大结构目录,容易看的懵逼,项目都是从一开始的几个文件然后内容的增多到很多个包,中间有慢慢衍生的过程,想一开始就把代码套在大骨架上实属勉强。
Vue配置文件中proxy我只是知道个大概的作用,只是在网上找到了这个解决方案,如果不加,直接在axios中裸用'http://localhost:5000',那么访问 到的地址就是打开浏览器访问页面时的那台机器的localhost资源,原因可能在于webpack4本身不知道'http://localhost:5000'这个地址,需要代理下!




参考资料:
Integrating Webpack 4 with a backend framework

Single Page Apps with Vue.js and Flask: Deployment

Running Frontend and Backend Development Servers Together

Simple SPA setup with Vue CLI 3 and Flask

flask-vuejs-template