4. 环境搭建与项目初始化:虚拟环境、依赖管理、项目目录结构设计(MVC模式)

好,咱们正式开始动手。前面三章讲了理念、流程和需求,现在该把袖子撸起来了。

这一章,我会带你从零搭建一个数据访问申请自动化项目的开发环境。说白了,就是让你的电脑准备好干活。我个人习惯,不管项目大小,第一步一定是搞虚拟环境。为什么?你想想看,Python 的依赖管理,说好听点叫灵活,说难听点就是一团乱麻。没有虚拟环境,你同时做两个项目,一个用 Flask 2.0,一个用 Flask 1.0,那你就等着哭吧。

4.1 虚拟环境:给你的项目一个“隔离区”

虚拟环境的作用,就是为每个项目创建一套独立的 Python 解释器和包依赖。这样项目 A 升级了某个库,完全不影响项目 B。

核心原则:每个项目,一个虚拟环境。不要共用,不要偷懒。

我推荐用 venv,它是 Python 3.3+ 自带的,不需要额外安装。当然,你也可以用 conda 或者 poetry,但咱们这个课程,用 venv 就够了,轻量、简单、没坑。

创建虚拟环境的命令很简单:

# 在项目根目录下执行
python -m venv venv

这条命令会在当前目录下生成一个 venv 文件夹,里面就是独立的 Python 环境。激活它:

# Windows
venv\Scripts\activate

# macOS / Linux
source venv/bin/activate

激活后,你的终端提示符前面会出现 (venv) 字样。这时候你安装的任何包,都只会进到这个环境里。

小技巧:我习惯在项目根目录下建一个 .gitignore 文件,把 venv/ 写进去。不然你把虚拟环境提交到 Git 仓库,那可就闹笑话了——几百兆的临时文件,别人拉下来还得重新建。

4.2 依赖管理:用 requirements.txt 锁死版本

环境搭好了,接下来装包。咱们这个数据访问申请流程自动化项目,需要哪些依赖?我列个清单:

包名 用途 推荐版本
Flask Web 框架,处理 HTTP 请求 2.3.x
Flask-SQLAlchemy ORM,操作数据库 3.0.x
Flask-Login 用户会话管理 0.6.x
Flask-WTF 表单处理与 CSRF 保护 1.1.x
email-validator 邮箱格式校验 2.0.x
python-dotenv 加载 .env 环境变量 1.0.x

安装命令:

pip install Flask==2.3.3 Flask-SQLAlchemy==3.0.5 Flask-Login==0.6.2 Flask-WTF==1.1.1 email-validator==2.0.0 python-dotenv==1.0.0

装完之后,立刻生成 requirements.txt:

pip freeze > requirements.txt

这个文件就是你的依赖清单。以后别人拿到项目,只需要执行 pip install -r requirements.txt,就能装上一模一样的包。

我曾经踩过的坑:有一次我忘了锁版本,直接 pip install flask 就完事了。结果三个月后同事拉代码,装上了 Flask 3.0,API 变了,项目直接跑不起来。所以,永远用 requirements.txt 锁死版本号,别偷懒。

4.3 项目目录结构设计:MVC 模式

环境搞定了,依赖也装好了,接下来是重头戏——项目目录结构。我见过太多新手把所有代码塞进一个 app.py 里,几百行代码挤在一起,改个功能要找半天。咱们这个项目,我采用经典的 MVC 模式来组织代码。

MVC 是什么?Model-View-Controller,模型-视图-控制器。说白了就是分层:

  • Model(模型):跟数据库打交道,定义数据结构。
  • View(视图):用户看到的页面,HTML 模板。
  • Controller(控制器):业务逻辑,处理请求,调用模型和视图。

下面是我设计的目录结构,你可以直接拿来用:

data-access-flow/
├── app/                    # 应用主目录
│   ├── __init__.py         # 应用工厂函数
│   ├── models/             # 数据模型
│   │   ├── __init__.py
│   │   ├── user.py         # 用户模型
│   │   └── request.py      # 申请单模型
│   ├── views/              # 路由和控制器
│   │   ├── __init__.py
│   │   ├── auth.py         # 登录/注册
│   │   └── request.py      # 申请流程
│   ├── templates/          # HTML 模板
│   │   ├── base.html
│   │   ├── auth/
│   │   └── request/
│   ├── static/             # 静态文件
│   │   ├── css/
│   │   └── js/
│   └── forms/              # WTForms 表单类
│       ├── __init__.py
│       ├── login_form.py
│       └── request_form.py
├── venv/                   # 虚拟环境
├── .env                    # 环境变量
├── .gitignore
├── requirements.txt
├── config.py               # 配置文件
└── run.py                  # 启动入口

这个结构,我用了好几年,改过很多版本,最终稳定成这个样子。它有几个好处:

  • 模块清晰:每个文件夹只做一件事,找代码不用猜。
  • 易于扩展:加一个新功能,只需要在 views/ 里加一个文件,在 models/ 里加一个模型,不影响现有代码。
  • 团队协作友好:两个人可以同时改不同的模块,不会冲突。

我的个人习惯:我会在 app/__init__.py 里写一个 create_app() 函数,这叫“应用工厂模式”。好处是方便测试,每个测试用例可以创建一个全新的应用实例,不会互相污染。后面咱们写单元测试的时候,你就知道这个设计有多香了。

下面这张图,展示了 MVC 模式下,数据在咱们这个项目里是怎么流动的:

MVC 架构数据流图 MVC 架构数据流图(数据访问申请流程) 用户 控制器 (Views) 模型 (Models) 视图 (Templates) 数据库 HTTP 请求 查询/写入 SQL 结果集 返回数据 渲染 HTML HTTP 响应 说明: 用户发起请求 → 控制器处理业务逻辑 → 模型操作数据库 → 控制器选择视图 → 视图渲染 HTML → 返回给用户

嗯,这张图把 MVC 的数据流向讲得很清楚了。用户点个按钮,请求先到控制器,控制器去问模型要数据,模型去查数据库,拿到数据返回给控制器,控制器再把数据塞给视图,视图渲染成 HTML 页面,最后回到用户浏览器。每一步职责分明,出了问题也好排查。

4.4 初始化项目:从零到可运行

目录结构有了,咱们把它变成能跑起来的代码。先写 config.py:

import os

class Config:
    SECRET_KEY = os.environ.get('SECRET_KEY') or 'dev-secret-key-change-in-production'
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or 'sqlite:///data_access.db'
    SQLALCHEMY_TRACK_MODIFICATIONS = False

再写 app/__init__.py,应用工厂:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from config import Config

db = SQLAlchemy()
login_manager = LoginManager()

def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)

    db.init_app(app)
    login_manager.init_app(app)

    from app.views import auth, request
    app.register_blueprint(auth.bp)
    app.register_blueprint(request.bp)

    return app

最后是启动入口 run.py:

from app import create_app

app = create_app()

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

到这里,项目骨架就搭好了。执行 python run.py,你应该能看到 Flask 启动的日志。虽然现在还没任何功能,但基础已经打牢了。

注意:SECRET_KEY 在生产环境一定要换成随机字符串,别用默认的。我见过有人把项目部署到服务器上,密钥还是 dev-secret-key,结果被攻击者伪造了 session,数据全丢了。这个坑,我替你们踩过了。