markdown “烧瓶项目的结构”笔记
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown “烧瓶项目的结构”笔记相关的知识,希望对你有一定的参考价值。
**[Structure of a Flask Project - Just lepture](https://lepture.com/en/2018/structure-of-a-flask-project)**
## Don't backward import from root\.\_\_init__.py
```python
# project/__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
db.init_app(app)
# project/auth/models.py
from .. import db
class User(db.Model):
# define columns
```
上述代码可以正常运行,但随着项目越来越复杂非常容易导致循环依赖的问题,例如:
```python
# project/__init__.py
from flask_sqlalchemy import SQLAlchemy
from another_extension import AnotherExtension
from project.auth.models import User
db = SQLAlchemy()
ext = AnotherExtension(User)
```
为了在\_\_init\_\_.py中导入User,需要导入auth.models,而auth.models又需要从\_\_init\_\_.py中导入db,因此造成循环依赖。循环依赖并非是Flask特有的问题,在官方文档中提供了解决此类问题的范例:**application factories**
```python
def create_app(config_filename):
app = Flask(__name__)
app.config.from_pyfile(config_filename)
from yourapplication.model import db
db.init_app(app)
from yourapplication.views.admin import admin
from yourapplication.views.frontend import frontend
app.register_blueprint(admin)
app.register_blueprint(frontend)
return app
```
上述代码中db不再直接定义在\_\_init\_\_.py中,而是定义在yourapplication.model中,然后通过导入yourapplication.model获取。
## 按照功能组织你的工程
Flask工程的典型结构如下:
```xml
project/
__init__.py
models/
__init__.py
base.py
users.py
posts.py
...
routes/
__init__.py
home.py
account.py
dashboard.py
...
templates/
base.html
post.html
...
services/
__init__.py
google.py
mail.py
...
```
所有的代码按照其实现的功能归类。在project/\_\_init__.py下定义create_app方法,然后在改方法中对所有使用的模块进行初始化:
```python
# project/__init__.py
from flask import Flask
def create_app()
from . import models, routes, services
app = Flask(__name__)
models.init_app(app)
routes.init_app(app)
services.init_app(app)
return app
```
这里使用了一点小技巧,在官方文档中Flask-SQLAlchemy的db是通过下面这种方式初始化的:
```python
from project.models import db
db.init_app(app)
```
所以我们可以在每个目录的\_\_init__.py中定义一个init_app方法,将各个模块的初始化过程规范化:
```python
# project/models/__init__.py
from .base import db
def init_app(app):
db.init_app(app)
# project/routes/__init__.py
from .users import user_bp
from .posts import posts_bp
# ...
def init_app(app):
app.register_blueprint(user_bp)
app.register_blueprint(posts_bp)
# ...
```
## 按照应用组织你的工程
除了按照功能组织工程,还可以按照代码归属的应用组织工程:
```xml
project/
__init__.py
db.py
auth/
__init__.py
route.py
models.py
templates/
blog/
__init__.py
route.py
models.py
templates/
...
```
在Dajongo中采用的就是这种组织方式。有时你甚至需要混用基于功能和基于应用的两种组织方式。同理我们也可以定义create_app对各个应用进行初始化:
```python
# project/__init__.py
from flask import Flask
def create_app()
from . import db, auth, blog
app = Flask(__name__)
db.init_app(app)
auth.init_app(app)
blog.init_app(app)
return app
```
## 配置管理
1. 在工程根目录下新建setting.py文件,作为静态配置文件
2. 从环境变量中加载配置
3. 通过create_app更新配置
下面是一个典型的配置文件结构:
```xml
conf/
dev_config.py
test_config.py
project/
__init__.py
settings.py
app.py
```
定义一个create_app来加载配置和环境变量:
```python
# project/__init__.py
import os
from flask import Flask
def create_app(config=None)
app = Flask(__name__)
# load default configuration
app.config.from_object('project.settings')
# load environment configuration
if 'FLASK_CONF' in os.environ:
app.config.from_envvar('FLASK_CONF')
# load app sepcified configuration
if config is not None:
if isinstance(config, dict):
app.config.update(config)
elif config.endswith('.py'):
app.config.from_pyfile(config)
return app
```
这里的FLASK_CONF指包含配置的python文件路径。
以上是关于markdown “烧瓶项目的结构”笔记的主要内容,如果未能解决你的问题,请参考以下文章