environment-setup:Python 虚拟环境管理、pip install flask 与首个规范 App
📂 所属阶段:第一阶段 — 破冰启航(基础篇)
🔗 相关章节:初识 Flask · 路由(Routing)艺术
1. 为什么必须用虚拟环境?
1.1 全局安装的致命坑
想象一个场景:
场景:你的老项目A依赖Flask 2.0,新项目B要尝鲜Flask 3.0的异步装饰器
→ 老项目全局更新Flask?直接报兼容性错误
→ 新项目迁就全局版本?错过新特性
→ 😱 只能拆机器?当然不是!
虚拟环境是解药:它为每个项目创建独立的「Python环境盒子」,里面的依赖、解释器路径完全隔离,互不干扰。
1.2 Python 3.3+ 自带的 venv 就够了
以前可能用 virtualenv、Pipenv,但现在 Python 官方已经把轻量、好用的 venv 内置进去(3.3+),无需额外安装任何第三方工具。
常用创建&激活命令
# 1. 创建虚拟环境(推荐用当前目录下的 venv 文件夹作为容器)
python -m venv venv
# 2. 激活虚拟环境(根据终端选择)
# ✅ Windows PowerShell(推荐先执行 Set-ExecutionPolicy RemoteSigned -Scope CurrentUser 解决权限限制)
.\venv\Scripts\Activate.ps1
# ✅ Windows CMD
venv\Scripts\activate.bat
# ✅ macOS / Linux(bash/zsh通用)
source venv/bin/activate
# 3. 验证激活成功(命令提示符前会带 (venv) 前缀)
(venv) PS D:\code_daoman\daoman_blog>
2. 安装 Flask 及规范依赖管理
2.1 基础起步:只装 Flask
如果是写练习项目,直接安装核心包就行:
2.2 实战推荐:安装常用扩展
做正式项目(比如这一系列的 DaoMan 博客),我们会用到这些高频扩展:
pip install \
flask \ # 核心 Web 框架
flask-sqlalchemy \ # ORM 数据库操作
flask-login \ # 用户认证
flask-wtf \ # 表单验证+CSRF防护
flask-migrate \ # Alembic 数据库迁移封装
flask-cors \ # 跨域请求处理
python-dotenv \ # 环境变量加载
email-validator # 邮箱格式验证
2.3 依赖清单:团队/部署必备
每次安装/卸载依赖后,务必更新依赖清单,方便在新机器一键恢复:
# 导出当前环境的依赖到 requirements.txt
pip freeze > requirements.txt
# 新机器/新克隆项目后,一键恢复所有依赖
pip install -r requirements.txt
更推荐的 requirements.txt 写法
全量导出 pip freeze 可能会带一些不必要的间接依赖,更推荐手动写核心依赖 + 版本范围,既清晰又安全(避免间接依赖的小版本 bug):
Flask>=3.0.0,<4.0.0
Flask-SQLAlchemy>=3.1.0,<4.0.0
Flask-Login>=0.6.3,<1.0.0
Flask-WTF>=1.2.0,<2.0.0
Flask-Migrate>=4.0.0,<5.0.0
Flask-CORS>=4.0.0,<5.0.0
python-dotenv>=1.0.0,<2.0.0
email-validator>=2.0.0,<3.0.0
3. 项目初始化(DaoMan 博客为例)
3.1 快速搭建项目骨架
按下面的命令一步步走,就能生成标准的 Flask 项目目录:
# 1. 创建项目根目录并进入
mkdir daoman_blog
cd daoman_blog
# 2. 初始化虚拟环境(记得激活!)
python -m venv venv
# 根据终端选择激活命令:.\venv\Scripts\Activate.ps1 或 source venv/bin/activate
# 3. 创建目录结构(手动 mkdir 或按下面的树形结构创建)
3.2 推荐的标准 Flask 目录结构
daoman_blog/
├── app/ # 应用核心代码包(重要!单独放代码)
│ ├── __init__.py # 应用工厂入口(create_app()函数)
│ ├── extensions.py # 扩展统一初始化(db/login_manager等)
│ ├── routes/ # 路由模块(用 Blueprint 拆分)
│ │ ├── __init__.py
│ │ ├── main.py # 首页/通用路由
│ │ ├── auth.py # 登录/注册/登出路由
│ │ └── articles.py # 文章相关路由
│ ├── models/ # ORM 数据模型
│ │ ├── __init__.py
│ │ └── user.py
│ ├── templates/ # Jinja2 模板文件
│ │ ├── base.html # 基础母模板(所有页面继承)
│ │ ├── index.html # 首页
│ │ └── auth/
│ │ └── login.html # 登录页
│ └── static/ # 静态资源(CSS/JS/图片/上传文件)
│ ├── css/
│ ├── js/
│ └── uploads/
├── migrations/ # Alembic 数据库迁移脚本(自动生成)
├── tests/ # 测试代码(pytest)
├── .env # 实际环境变量(含密钥,**绝对不上传Git**)
├── .env.example # 环境变量模板(上传Git,给协作者参考)
├── .gitignore # Git 忽略文件配置
├── requirements.txt # 依赖清单
├── config.py # 项目配置文件(开发/测试/生产分离)
└── run.py # 启动脚本
💡 提示:初学者可以先手动创建这些文件夹和空文件,后续章节会逐步填充内容。保持结构清晰比什么都重要。
4. 应用工厂模式(Flask 官方推荐)
为什么要用应用工厂?
- 🧩 支持多环境切换:开发、测试、生产配置一键搞定
- 🔁 避免循环导入:比如 routes 导入 db,db 导入 app 这类问题
- 🧪 方便编写测试:可以创建多个独立的测试实例
4.1 第一步:统一初始化扩展
新建 app/extensions.py,把所有扩展先实例化,暂时不绑定 app:
# app/extensions.py
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from flask_migrate import Migrate
from flask_wtf.csrf import CSRFProtect
# 实例化所有扩展(不带app参数)
db = SQLAlchemy()
login_manager = LoginManager()
migrate = Migrate()
csrf = CSRFProtect()
# 配置 login_manager
login_manager.login_view = "auth.login" # 未登录用户自动跳转到登录页
login_manager.login_message = "请先登录后再访问该页面哦~"
login_manager.login_message_category = "info" # 消息提示的样式类(Bootstrap用)
4.2 第二步:应用工厂函数
新建 app/__init__.py,编写 create_app(config_name) 函数:
# app/__init__.py
from flask import Flask
from config import config
from app.extensions import db, login_manager, migrate, csrf
def create_app(config_name="development"):
# 1. 创建 Flask 实例
app = Flask(__name__)
# 2. 加载对应环境的配置
app.config.from_object(config[config_name])
# 3. 绑定扩展到当前 app
db.init_app(app)
login_manager.init_app(app)
migrate.init_app(app, db)
csrf.init_app(app)
# 4. 注册 Blueprint(路由拆分)
from app.routes.main import main_bp
from app.routes.auth import auth_bp
app.register_blueprint(main_bp)
app.register_blueprint(auth_bp, url_prefix="/auth") # 加前缀避免路由冲突
# 5. (可选)添加简单的错误处理
# 6. 返回配置好的 app 实例
return app
4.3 第三步:多环境配置文件
新建 config.py,分离开发/测试/生产的配置:
# config.py
import os
from dotenv import load_dotenv
# 加载项目根目录的 .env 文件
load_dotenv()
class BaseConfig:
"""基础配置(所有环境共用)"""
SECRET_KEY = os.getenv("SECRET_KEY", "dev-secret-key-123-CHANGE-ME-IN-PRODUCTION")
SQLALCHEMY_TRACK_MODIFICATIONS = False # 关闭不必要的数据库修改追踪
UPLOAD_FOLDER = os.path.join(os.path.dirname(__file__), "app/static/uploads")
class DevelopmentConfig(BaseConfig):
"""开发环境配置"""
DEBUG = True
SQLALCHEMY_DATABASE_URI = os.getenv("DEV_DATABASE_URL", "sqlite:///daoman_dev.db")
class ProductionConfig(BaseConfig):
"""生产环境配置"""
DEBUG = False
SQLALCHEMY_DATABASE_URI = os.getenv("PROD_DATABASE_URL", "postgresql://user:pass@localhost/daoman_prod")
class TestingConfig(BaseConfig):
"""测试环境配置"""
TESTING = True
SQLALCHEMY_DATABASE_URI = "sqlite:///:memory:" # 内存数据库,测试完自动清空
WTF_CSRF_ENABLED = False # 测试时关闭 CSRF 验证
# 配置字典,供 create_app() 调用
config = {
"development": DevelopmentConfig,
"production": ProductionConfig,
"testing": TestingConfig,
"default": DevelopmentConfig,
}
4.4 第四步:启动脚本
新建 run.py,作为项目的入口文件:
# run.py
import os
from app import create_app
# 从环境变量读取配置名,默认用开发环境
config_name = os.getenv("FLASK_ENV", "development")
app = create_app(config_name)
if __name__ == "__main__":
app.run(
host="127.0.0.1", # 本地访问
port=5000,
debug=config[config_name].DEBUG, # 同步环境的DEBUG配置
)
5. 敏感信息与 Git 规范
5.1 用 .env 管理密钥和敏感配置
直接把密钥写在 config.py 里非常危险,会被上传到 Git 公开!必须用 python-dotenv 加载外部的 .env 文件。
.env 和 .env.example 的区别
# .env(实际使用的,**绝对不能上传 Git**)
SECRET_KEY=230894d23c892b123a123d789f123a456c789d01
DEV_DATABASE_URL=sqlite:///daoman_dev.db
PROD_DATABASE_URL=postgresql://daoman_user:daoman_pass123@127.0.0.1:5432/daoman_prod
FLASK_ENV=development
# .env.example(模板,**必须上传 Git**,给协作者参考)
SECRET_KEY=change-this-to-a-strong-random-secret
DEV_DATABASE_URL=sqlite:///daoman_dev.db
PROD_DATABASE_URL=postgresql://user:pass@localhost/db_name
FLASK_ENV=development
5.2 .gitignore 配置
新建 .gitignore,忽略所有不必要的文件:
# .gitignore
# 虚拟环境
venv/
.venv/
# Python 缓存
__pycache__/
*.py[cod]
*$py.class
# 数据库
*.db
*.sqlite
*.sqlite3
# 环境变量
.env
.env.local
# IDE 配置
.vscode/
.idea/
*.swp
*.swo
# 上传文件(可选)
app/static/uploads/*
!app/static/uploads/.gitkeep # 保留空文件夹到Git
# 测试覆盖率
.coverage
htmlcov/
6. 小结与验证清单
6.1 项目初始化快速验证清单
现在你应该已经完成了所有步骤,按下面的清单验证是否成功:
✅ 虚拟环境已创建并激活
✅ requirements.txt 已生成或手动编写
✅ 标准目录结构已建立
✅ 应用工厂模式已实现
✅ .env 和 .env.example 已创建
✅ .gitignore 已配置
✅ 运行 python run.py 能正常启动(访问 http://127.0.0.1:5000 会显示404,因为还没写首页路由~)
6.2 最佳实践提醒
💡 敲黑板:从第一天起就使用虚拟环境和应用工厂模式!虽然最小应用(比如 hello.py)可以直接写在一个文件里,但养成规范习惯能避免以后重构的巨大痛苦。
🔗 扩展阅读