当前位置: 首页 > article >正文

前端Python应用指南(二)深入Flask:理解Flask的应用结构与模块化设计

《写给前端的python应用指南》系列:

  • (一)快速构建 Web 服务器 - Flask vs Node.js 对比

书接上文,这一篇将会深入了解下Flask,这个轻量级的Web框架,非常适合用来构建小型应用和快速原型开发。但是,随着应用规模的扩大,我们往往会遇到代码膨胀和难以管理的问题(这个问题在几乎所有的开发中都会遇到。通过深入探讨Flask应用的结构,学会如何将其模块化设计,能帮助你更好地构建可扩展、易维护的大型Flask应用。

另外我发现不少全栈岗位,是以python和java作为后端的,Nodejs的有,但一般很少,甚至他们招熟练使用Nodejs的开发人员,进去后再全栈开发 - 相当于用前端的价格招全栈人员,而我就是这样的,然后我也这样招人,因为符合条件的人员真不多。但实践了一两年,发现重新培养全栈同事是很难的事情,不只是知识面广需要主动研究,还有就是上下文切换(代码允许在什么环境)。不如出个文章,至少看完本文,说明你对全栈开发是感兴趣,而不是被逼着学的 - 现在我再做导师一类的,也不会逼人学什么了,自己研究我的文章去

一、Flask应用的基本结构

Flask虽然是一个“微框架”,但它的结构非常灵活,允许你根据项目需求自由组织代码,是可以扩展到中大型应用。一个简单的Flask应用通常有如下结构:

/my_flask_app
    /app
        __init__.py
        routes.py
        models.py
        templates/
        static/
    /instance
        config.py
    run.py

这个结构和常用的后端应用差不多,例如express,也会有config、app、routes、models、public/static,用到模板引擎则有templates,万变不离其宗,虽然语言不同但做的事情或者目标相差无几 - CRUD,生成页面,读取数据,调用与整合接口数据

1. __init__.py

__init__.py是Flask应用的核心,它负责初始化Flask应用及其配置、路由和数据库等部分。通常,我们会在这个文件中创建Flask实例,并进行应用相关的配置。

2. routes.py

routes.py是定义应用路由的地方。Flask应用的每个URL都会映射到一个视图函数,而路由则是URL和视图函数的绑定。

3. models.py

models.py通常用于定义数据库模型,尤其是在使用ORM(如SQLAlchemy)时,用于创建数据库表的模型类。

4. templates/static/

这两个文件夹分别用于存放HTML模板文件和静态资源(如CSS、JavaScript文件、图片等)。Flask使用Jinja2模板引擎来渲染HTML页面。

5. instance/config.py

config.py用于存放应用的配置项,可以是数据库配置、API密钥、日志设置等。我们通常将配置文件放在instance目录中,以保持安全性和灵活性。

6. run.py

run.py是Flask应用的启动入口,运行Flask应用时,通常会通过该文件来启动应用。

二、如何实现Flask应用的模块化设计

随着项目规模的增长,单个文件会变得冗长且难以维护。为了提高代码的可读性和可扩展性,我们需要将Flask应用进行模块化。Flask允许我们使用“蓝图”(Blueprint)来实现这一点。蓝图是Flask的核心特性之一,它能够将应用分成多个模块,每个模块负责一个独立的功能或业务领域。

1. 创建蓝图

一个典型的Flask项目可以根据功能划分成多个模块,例如用户认证、文章管理、评论系统等。每个模块都可以定义一个蓝图。蓝图通过Flask.register_blueprint()来注册到主应用上。

蓝图类似于一个子路由,抽象的route,除非挂载不起作用,和express的route类似
比较小的项目我个人并不推荐用,或许将各个处理方法整理,在使用的地方挂载就可以了

示例:创建一个用户模块的蓝图
# app/auth/routes.py

from flask import Blueprint

auth = Blueprint('auth', __name__)

@auth.route('/login')
def login():
    return "Login Page"

@auth.route('/logout')
def logout():
    return "Logout Page"

在上面的代码中,我们定义了一个名为auth的蓝图,并为其添加了/login/logout两个路由。接下来,我们需要将这个蓝图注册到主应用中。

主应用中注册蓝图
# app/__init__.py

from flask import Flask
from .auth.routes import auth

def create_app():
    app = Flask(__name__)
    app.register_blueprint(auth, url_prefix='/auth')
    return app

create_app()函数中,我们将auth蓝图注册到主应用上,并为它指定了一个URL前缀/auth。这样,/login/logout的路由就变成了/auth/login/auth/logout

2. 模块化视图函数

除了路由,Flask的视图函数也可以进行模块化。对于大型项目,我们可以根据不同的功能将视图函数拆分到不同的文件中。这样做可以避免将所有代码堆积在一个文件里,增加代码的可读性。

仁者见仁智者见智,其实我是推荐视图在一个文件“挂载”,但仅仅是挂载,类似请求路由->处理函数的映射比表,不在这里写其它逻辑,对于整个应用的掌控更好,尤其是微服务应用

示例:将路由与视图分离
# app/auth/views.py

from .routes import auth

@auth.route('/profile')
def profile():
    return "User Profile"

在这个例子中,我们将profile视图函数从routes.py中提取到了一个单独的views.py文件中。这有助于将业务逻辑与路由定义分离,增强代码的可维护性。

3. 模块化模型和数据库操作

Flask和SQLAlchemy结合使用时,模型通常是存放在单独的models.py中。然而,如果项目越来越大,多个模块可能会有不同的数据库模型。为了避免在一个文件中定义所有模型,可以将模型分开管理。

示例:模块化数据库模型
# app/auth/models.py

from . import db

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

models.py文件中定义的模型类可以通过蓝图或应用来使用。每个模块都可以定义与其功能相关的模型,并在主应用中进行注册。

4. 配置与环境分离

为了更好地管理应用配置,Flask允许我们在不同的环境(开发、测试、生产)中使用不同的配置文件。在Flask中,我们通常使用config.py来管理配置项,并通过from_object()方法加载配置。

示例:加载配置文件
# app/__init__.py

import os
from flask import Flask

def create_app(config_name=None):
    app = Flask(__name__)
    
    # 默认加载开发环境配置
    app.config.from_object(config_name or 'config.DevelopmentConfig')
    
    return app

在不同的环境中,可以通过加载不同的配置文件来管理数据库连接、日志记录等。

三、总结

通过蓝图和模块化设计,Flask应用能够轻松地扩展和维护。无论是路由、视图函数还是数据库模型,都可以被拆分到不同的模块中,避免了代码的膨胀和管理困难。通过合理的模块化设计,你的Flask应用将变得更加清晰、灵活和易于维护。

在这篇文章中,我们重点介绍了Flask应用的基本结构以及如何通过蓝图实现模块化。希望通过这篇文章,你能够更好地理解Flask的架构设计,并在实际开发中应用这些技巧构建高效、可维护的Flask应用。


http://www.kler.cn/a/450602.html

相关文章:

  • MacOS M3源代码编译Qt6.8.1
  • c++ [spdlog 配置与使用]
  • f(f(x))=x^2 -11x+36, 求f(6)的值,
  • JAVA HTTP压缩数据
  • 【论文复现】农作物病害分类(Web端实现)
  • java Redis 操作工具类封装(备忘)
  • 1688商品详情api接口开发返回值说明中skus商品规格和props商品详情
  • leetcode hot100 两两交换链表之中的节点
  • 深度学习从入门到精通——图像分割实战DeeplabV3
  • 基于Springboot的在线问卷调查系统【附源码】
  • JVM执行引擎JIT深度剖析
  • 【MySQL】InnoDB存储引擎中的索引
  • 深入理解C++23的Deducing this特性(下):高级应用与实战技巧
  • mapbox基础,加载mapbox官方地图
  • RGCL:A Review-aware Graph Contrastive Learning Framework for Recommendation
  • 自动驾驶系统研发系列—追尾风险不再隐形:解密后碰撞预警系统(RCW)的技术与应用
  • 交通控制系统中的 Prompt工程:引导LLMs实现高效交叉口管理 !
  • ensp 基于静态NAT发布公司网站服务器,
  • WebGL2示例项目常见问题解决方案
  • Wireshark时间设置介绍:时间格式、时间参考和时间平移
  • [Linux] Shell 命令及运行原理
  • 测开面经分享(偏Python)
  • 【双指针算法】--复写零
  • 编程新选择:深入了解仓颉语言的优雅与高效
  • 华为OD E卷(100分)32-字符串分割
  • C中设计不允许继承的类的实现方法是什么?