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 “烧瓶项目的结构”笔记的主要内容,如果未能解决你的问题,请参考以下文章

关于印象笔记与markdown,你需要知道这些

windows 为知笔记怎么写markdown

有道云笔记 markdown怎么插入excel附件

快速输入有道云笔记markdown公式符号

如何在为知笔记中用Markdown创建目录大纲

如何在为知笔记中用Markdown创建目录大纲