python flask项目架构搭建

发布于:2025-03-19 ⋅ 阅读:(16) ⋅ 点赞:(0)

python flask项目1-创建flask项目

搭建简单的flask项目

简单的flask项目架构

开始搭建简单的flask项目架构。
一般的flask 项目中,通常使用app目录和app.py文件,比较容易弄混淆,这里我使用有区别性的名字,让引用及路径清晰可见,最后再给出比较正规的命名。

demo项目架构如下:

python_test
  -flask_app.py
  -flask_test_app
     -_init_.py
     - views
       - _init_.py
       - myview.py

flask_app.py内容如下:

from flask import Flask 
from flask_test_app import  create_app


configs={}
app=create_app(configs)

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

Flask安装版本 2.3.2

configs可以是从文件中读取的根据传入的环境参数决定的配置内容

create_app是使用工厂模式来初始化flask app,在flask_test_app/init.py中定义,代码如下:

from flask import Flask 
from flask_sqlalchemy import SQLAlchemy
from flask_cofig import get_db_link

db = SQLAlchemy() 

def create_app(config): 
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI']  =  get_db_link()
    db.init_app(app)  
    #延迟导入蓝图,避免循环
    from flask_test_app.views import testview
    app.register_blueprint(testview)
    return app 

SQLAlchemy版本:2.0.39

在create_app中延迟导入蓝图,避免循环

views下定义视图及路由,views/init.py:

from flask import Blueprint
  
testview=Blueprint("test_view",__name__)
# 最后导入路由(确保蓝图已存在)
from .myview import *  


定义视图:testview=Blueprint(“test_view”,name)

最后需要导入路由views下路由文件:from .myview import * ,另外使用相对导入(from . import module)避免跨模块依赖。

注意,这行代码若放在前面,造成 在 views/init.py 中先导入 myview ,myview中视图会使用testview。就会造成错误,先引用再定义 testview,导致 myview 反向引用未初始化的蓝图。

views/myview.py内容如下:

from . import testview

@testview.route('/test_now') 
def add_user():
    return "test_now"

启动项目:

flask run --no-debugger --host 127.0.0.1 --port 5000 

此框架适合大中型项目扩展,如需添加更多蓝图,只需在 views 目录下新建模块并遵循相同模式即可。

比较正规的flask项目结构

在 Flask 项目中使用 工厂模式(Factory Pattern) 是一种非常常见的做法。工厂模式的核心思想是将应用的创建过程封装到一个函数中,而不是直接在全局范围内创建应用实例。这种方式可以更好地组织代码,支持多环境配置(如开发、测试、生产),并且更容易进行单元测试。

以下是如何使用工厂模式创建一个 Flask 应用的详细步骤和示例:


1. 工厂模式的优势

  • 灵活性:可以根据不同的配置(如开发、测试、生产)创建不同的应用实例。
  • 可测试性:可以轻松地为测试创建独立的应用实例。
  • 模块化:将应用的创建逻辑封装到一个函数中,代码更清晰、更易于维护。

2. 项目结构

一个典型的 Flask 工厂模式项目结构如下:

my_flask_app/
├── app/
│   ├── __init__.py       # 工厂函数和扩展初始化
│   ├── routes.py         # 路由定义
│   ├── models.py         # 数据库模型
│   ├── config.py         # 配置文件
│   └── templates/        # 模板文件
├── tests/                # 单元测试
│   └── test_routes.py
├── requirements.txt      # 依赖文件
└── app.py                # 启动脚本

3. 实现步骤

3.1 创建工厂函数

app/__init__.py 中定义工厂函数 create_app,用于创建 Flask 应用实例。

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

# 初始化扩展
db = SQLAlchemy()

def create_app(config_class='config.DevelopmentConfig'):
    """
    工厂函数,用于创建 Flask 应用实例。
    :param config_class: 配置类(默认使用开发环境配置)
    :return: Flask 应用实例
    """
    app = Flask(__name__)

    # 加载配置
    app.config.from_object(config_class)

    # 初始化扩展
    db.init_app(app)

    # 注册路由
    from app.routes import main_routes
    app.register_blueprint(main_routes)

    return app
3.2 配置文件

app/config.py 中定义不同环境的配置类。

import os

class Config:
    # 通用配置
    SECRET_KEY = os.getenv('SECRET_KEY', 'default-secret-key')
    SQLALCHEMY_TRACK_MODIFICATIONS = False

class DevelopmentConfig(Config):
    # 开发环境配置
    DEBUG = True
    SQLALCHEMY_DATABASE_URI = 'sqlite:///dev.db'

class TestingConfig(Config):
    # 测试环境配置
    TESTING = True
    SQLALCHEMY_DATABASE_URI = 'sqlite:///test.db'

class ProductionConfig(Config):
    # 生产环境配置
    SQLALCHEMY_DATABASE_URI = os.getenv('DATABASE_URL', 'sqlite:///prod.db')
3.3 定义路由

app/routes.py 中定义应用的路由。

from flask import Blueprint

# 创建蓝图
main_routes = Blueprint('main', __name__)

@main_routes.route('/')
def index():
    return "Hello, Flask Factory Pattern!"
3.4 定义模型

app/models.py 中定义数据库模型。

from app import db

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)

    def __repr__(self):
        return f'<User {self.username}>'
3.5 启动脚本

app.py 中创建应用实例并启动开发服务器。

from app import create_app

app = create_app()

if __name__ == '__main__':
    app.run(debug=True)
3.6 单元测试

tests/test_routes.py 中编写单元测试。

import unittest
from app import create_app

class TestRoutes(unittest.TestCase):
    def setUp(self):
        self.app = create_app(config_class='config.TestingConfig')
        self.client = self.app.test_client()

    def test_index(self):
        response = self.client.get('/')
        self.assertEqual(response.status_code, 200)
        self.assertIn(b'Hello, Flask Factory Pattern!', response.data)

if __name__ == '__main__':
    unittest.main()

4. 运行项目

4.1 安装依赖

在项目根目录下创建 requirements.txt 文件,并安装依赖。

Flask==2.3.2
Flask-SQLAlchemy==3.0.5

运行以下命令安装依赖:

pip install -r requirements.txt
4.2 启动开发服务器

运行 run.py 启动开发服务器:

python app.py

访问 http://127.0.0.1:5000/,你会看到 “Hello, Flask Factory Pattern!”。

4.3 运行单元测试

运行以下命令执行单元测试:

python -m unittest tests/test_routes.py

5. 总结

通过工厂模式创建 Flask 应用,可以更好地组织代码,支持多环境配置,并提高代码的可测试性和可维护性。以下是关键点:

  1. 工厂函数:在 app/__init__.py 中定义 create_app 函数。
  2. 配置文件:在 app/config.py 中定义不同环境的配置类。
  3. 模块化:将路由、模型、扩展初始化等逻辑拆分到不同的文件中。
  4. 测试:使用工厂函数创建独立的应用实例进行单元测试。

这种结构非常适合中大型 Flask 项目,能够有效管理复杂性和扩展性。

多模块的flask项目结构

在大型 Flask 项目中,通常会将应用拆分为多个模块,每个模块负责不同的功能。为了更好地组织代码,可以将路由和视图函数进一步细分到 app/views 目录中,并为每个模块创建子文件夹。以下是基于这种需求的 Flask 工厂模式的组织方式:


1. 项目结构

假设项目分为 auth(认证模块)和 blog(博客模块),项目结构如下:

my_flask_app/
├── app/
│   ├── __init__.py           # 工厂函数和扩展初始化
│   ├── config.py             # 配置文件
│   ├── models.py             # 数据库模型
│   ├── views/                # 视图模块
│   │   ├── auth/             # 认证模块
│   │   │   ├── __init__.py
│   │   │   └── auth_views.py      # 认证模块的视图函数
│   │   └── blog/             # 博客模块
│   │       ├── __init__.py
│   │       └── blog_views.py      # 博客模块的视图函数
│   └── templates/            # 模板文件
├── tests/                    # 单元测试
│   ├── test_auth.py
│   └── test_blog.py
├── requirements.txt          # 依赖文件
└── app.py                    # 启动脚本

2. 实现步骤

2.1 工厂函数

app/__init__.py 中定义工厂函数 create_app,并初始化扩展和模块。

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

# 初始化扩展
db = SQLAlchemy()

def create_app(config_class='config.DevelopmentConfig'):
    """
    工厂函数,用于创建 Flask 应用实例。
    :param config_class: 配置类(默认使用开发环境配置)
    :return: Flask 应用实例
    """
    app = Flask(__name__)

    # 加载配置
    app.config.from_object(config_class)

    # 初始化扩展
    db.init_app(app)

    # 注册模块
    register_blueprints(app)

    return app

def register_blueprints(app):
    """
    注册所有模块的蓝图。
    """
    from app.views.auth import auth_bp
    from app.views.blog import blog_bp

    app.register_blueprint(auth_bp)
    app.register_blueprint(blog_bp)
2.2 配置文件

app/config.py 中定义不同环境的配置类。

import os

class Config:
    # 通用配置
    SECRET_KEY = os.getenv('SECRET_KEY', 'default-secret-key')
    SQLALCHEMY_TRACK_MODIFICATIONS = False

class DevelopmentConfig(Config):
    # 开发环境配置
    DEBUG = True
    SQLALCHEMY_DATABASE_URI = 'sqlite:///dev.db'

class TestingConfig(Config):
    # 测试环境配置
    TESTING = True
    SQLALCHEMY_DATABASE_URI = 'sqlite:///test.db'

class ProductionConfig(Config):
    # 生产环境配置
    SQLALCHEMY_DATABASE_URI = os.getenv('DATABASE_URL', 'sqlite:///prod.db')
2.3 认证模块

app/views/auth/ 目录中定义认证模块的路由和视图函数。

  • app/views/auth/__init__.py

    from flask import Blueprint
    
    # 创建蓝图
    auth_bp = Blueprint('auth', __name__)
    
    from . import auth_views
    
  • app/views/auth/auth_views.py

from flask import render_template
from app.views.auth import auth_bp

@auth_bp.route(‘/’)
def login():
return render_template(‘auth/login.html’)

@auth_bp.route(‘/logout’)
def logout():
return “Logout Page”


#### **2.4 博客模块**
在 `app/views/blog/` 目录中定义博客模块的路由和视图函数。

- **`app/views/blog/__init__.py`**:

```python
from flask import Blueprint
from .views import index, post

# 创建蓝图
blog_bp = Blueprint('blog', __name__)

from . import blog_views 
  • app/views/blog/blog_views.py

from flask import render_template
from app.views.blog import blog_bp

@blog_bp.route(‘/’)
def index():
return render_template(‘blog/index.html’)

@blog_bp.route(‘/post/int:post_id’)
def post(post_id):
return f"Post {post_id}"


#### **2.5 启动脚本**
在 `run.py` 中创建应用实例并启动开发服务器。

```python
from app import create_app

app = create_app() #这里可以传选定环境的config类

if __name__ == '__main__':
  app.run(debug=True)
2.6 单元测试

tests/ 目录中编写单元测试。

  • tests/test_auth.py

    import unittest
    

from app import create_app

class TestAuthRoutes(unittest.TestCase):
def setUp(self):
self.app = create_app(config_class=‘config.TestingConfig’)
self.client = self.app.test_client()

  def test_login(self):
      response = self.client.get('/login')
    self.assertEqual(response.status_code, 200)

if name == ‘main’:
unittest.main()

  
- **`tests/test_blog.py`**:
  ```python
  import unittest
  from app import create_app

  class TestBlogRoutes(unittest.TestCase):
      def setUp(self):
          self.app = create_app(config_class='config.TestingConfig')
          self.client = self.app.test_client()

      def test_index(self):
          response = self.client.get('/')
          self.assertEqual(response.status_code, 200)

  if __name__ == '__main__':
      unittest.main()

3. 运行项目

3.1 安装依赖

在项目根目录下创建 requirements.txt 文件,并安装依赖。

Flask==2.3.2
Flask-SQLAlchemy==3.0.5

运行以下命令安装依赖:

pip install -r requirements.txt
3.2 启动开发服务器

运行 run.py 启动开发服务器:

python app.py

访问以下 URL 测试应用:

  • http://127.0.0.1:5000/login(认证模块)
  • http://127.0.0.1:5000/(博客模块)
3.3 运行单元测试

运行以下命令执行单元测试:

python -m unittest tests/test_auth.py
python -m unittest tests/test_blog.py

4. 总结

通过将项目拆分为多个模块,并使用工厂模式组织代码,可以实现以下目标:

  1. 模块化:每个模块独立管理自己的路由和视图函数。
  2. 可维护性:代码结构清晰,易于扩展和维护。
  3. 可测试性:每个模块可以独立测试。

这种组织方式非常适合大型 Flask 项目,能够有效管理复杂性和扩展性。