21-接手Django老项目(上)-环境复现与依赖地狱突围

21-接手Django老项目(上)-环境复现与依赖地狱突围 文章目录接手Django老项目我第一步做的不是看代码——环境复现与依赖地狱突围导入语1 ~ 拿到仓库后第一件该做的事——不是 git clone1.1 正确的检查顺序2 ~ requirements.txt 的暗坑2.1 直接 pip install -r requirements.txt 为什么危险2.2 pip freeze 的版本锁定问题2.3 我踩过的坑——下架的包3 ~ Python 版本管理——conda vs pyenv vs 直接用系统 Python3.1 为什么不要直接用系统 Python3.2 我的实践4 ~ 数据库驱动——Django 项目的头号环境杀手4.1 mysqlclient 的编译地狱4.2 PostgreSQL 的 psycopg2 同样问题5 ~ settings.py 中那些硬编码的秘密5.1 数据库密码写死在 settings.py 里——最常见的错误思考 总结结尾接手Django老项目我第一步做的不是看代码——环境复现与依赖地狱突围文章简介拿到一个 Django 老项目的仓库地址新手的第一反应是 clone 下来直接python manage.py runserver——然后迎面撞上ModuleNotFoundError、mysqlclient编译失败、Python 版本不匹配三连击。本文是接手老项目系列的上篇聚焦环境复现的完整流程从requirements.txt的版本锁定策略到pip freeze的陷阱、从virtualenv到pipenv的演进、从 MySQL 驱动安装的坑到settings.py数据库配置的安全实践。穿插真实经历——接手一个 Python 3.6 的 Django 2.0 项目光是让它在本地跑起来就花了两天。 个人主页源码骑士❄专栏传送门《Android开发基础》《python基础课程》⭐️热衷从源码视角拆解技术底层原理将复杂架构讲得通俗易懂 源码骑士的简介5年Android Framework系统开发经验曾主导多项系统级性能优化专项技术栈覆盖Android系统全链路Binder/Handler/AMS/WMS/启动流程及Java后端全家桶Spring MyBatis Redis Oracle累计产出原创技术文章100篇文章以源码拆解为特色被读者评价为看一篇胜过啃一周文档导入语2021 年我接手了公司一个内部管理系统——Django 2.0 Python 3.6最后一次提交是 2019 年 3 月。当时的想法很简单clone 下来装依赖跑起来看代码。结果从 clone 到runserver成功输出 “Starting development server”花了我整整两天。原因不是代码复杂——而是环境。Python 3.6 在 2021 年已经不好装了mysqlclient在 Windows 上编译需要 Visual C Build Toolsrequirements.txt里还有两个包已经从 PyPI 下架了。你以为的核心工作是看代码实际上的核心工作是让代码跑起来。这篇文章是接手老项目系列的上篇专讲环境复现这条路上的坑和正确的趟法。1 ~ 拿到仓库后第一件该做的事——不是git clone1.1 正确的检查顺序# 第一条命令——不是 git clone不是 pip installgitlog--oneline-20# 看最近 20 次提交了解项目活跃度和最近改动方向# 第二条命令catREADME.md# 看有没有环境说明Python版本、数据库类型、部署方式# 第三条——检查 Python 版本要求catruntime.txt# 或 .python-version# 如果都没有看 setup.py 或 pyproject.toml 中的 python_requires这三条命令能帮你避免后续一半的坑。我那个 Django 2.0 项目 README 里什么都没写但我从 git log 看出最后一次提交涉及升级 Django 1.11 → 2.0——说明这个项目经历过版本迁移代码中可能有旧 API 残留。2 ~requirements.txt的暗坑2.1 直接pip install -r requirements.txt为什么危险# 典型的老项目 requirements.txtDjango2.0.13mysqlclient1.3.14celery4.2.1redis3.0.1看起来很正常。但你执行pip install -r requirements.txt之后可能会遇到ERROR: Could not find a version that satisfies the requirement mysqlclient1.3.14 ERROR: No matching distribution found for mysqlclient1.3.14这个包的这个版本可能在你当前的 Python 小版本上不可用。或者更糟——这个包已经从 PyPI 下架了。2.2pip freeze的版本锁定问题pip freeze requirements.txt只会锁定显式安装的包不会锁定依赖的依赖。也就是说——你这个项目依赖celery4.2.1而 celery 又依赖kombu。两年前kombu的某个版本是兼容的但今天如果你只锁了 celery 不锁 kombupip 会安装最新版 kombu——然后运行时爆炸。正确做法用pip-compile来自pip-tools或pipenv lock生成完整的依赖锁文件包括所有传递依赖。2.3 我踩过的坑——下架的包2021 年那个项目中有一个django-extended-choices包已经从 PyPI 下架。pip install 报 404。解决方案是——去 PyPI 的历史包网站找到最后一个版本的.tar.gz手动下载放到项目目录中用pip install ./django-extended-choices-1.3.tar.gz安装。教训接手老项目时先不要试图一步到位装所有依赖。先看 requirements.txt 里有几个包你还认识不认识的上 PyPI 搜一下是否还存在。3 ~ Python 版本管理——conda vs pyenv vs 直接用系统 Python3.1 为什么不要直接用系统 Python$ python3--versionPython3.10.6项目要求 Python 3.6。系统 Python 是 3.10。你直接pip install Django2.0.13可能装得上但 Django 2.0 最后支持的 Python 版本是 3.7——在 3.10 上可能有微小的语法变化不兼容。工具选择工具适合什么不适合什么pyenvLinux/macOS轻量只管 Python 版本Windows不支持conda跨平台连二进制包都能管安装慢占用空间大pipenv自带虚拟环境 依赖管理解析依赖慢virtualenvpip最轻量的基础方案自己管理 Python 版本3.2 我的实践# 第一步装对 Python 版本pyenvinstall3.6.15# 第二步创建项目专用的虚拟环境pyenv virtualenv3.6.15 myproject-env pyenvlocalmyproject-env# 第三步确认版本python--version# 必须输出 3.6.154 ~ 数据库驱动——Django 项目的头号环境杀手4.1mysqlclient的编译地狱pipinstallmysqlclient# Windows: error: Microsoft Visual C 14.0 is required# Linux: fatal error: mysql.h: No such file or directorymysqlclient是 C 扩展——它需要编译。Windows 上要装 Visual C Build Tools几 GB 的下载Linux 上要装libmysqlclient-dev。最快方案如果不需要严格的 mysqlclientpipinstallpymysql# 然后在 Django settings.py 同级目录的 __init__.py 中加importpymysql pymysql.install_as_MySQLdb()pymysql是纯 Python 实现不需要编译。但对于生产环境的高并发场景mysqlclient的性能更好——它是 C 写的。4.2 PostgreSQL 的psycopg2同样问题# Linuxsudoaptinstalllibpq-dev python3-dev pipinstallpsycopg25 ~ settings.py 中那些硬编码的秘密5.1 数据库密码写死在 settings.py 里——最常见的错误# settings.py——不要把这种代码和项目一起提交到 GitDATABASES{default:{ENGINE:django.db.backends.mysql,NAME:production_db,USER:admin,PASSWORD:MySecret123,# ← 生产密码在代码里HOST:10.0.1.50,}}正确做法# settings.pyimportos DATABASES{default:{ENGINE:django.db.backends.mysql,NAME:os.environ.get(DB_NAME,mydb),USER:os.environ.get(DB_USER,root),PASSWORD:os.environ.get(DB_PASSWORD,),HOST:os.environ.get(DB_HOST,localhost),}}环境变量用.env文件管理python-decouple或django-environ.env必须加到.gitignore。思考 总结接手老项目的环境复现有三步优先级先读 README 和 git log——确定 Python 版本和数据库类型。用版本管理工具pyenv/conda装对 Python——别图省事直接用系统 Python。依赖安装从核心包开始Django 本身→ 数据库驱动 → celery 等外围服务——逐个排查别一把梭pip install -r requirements.txt。结尾上篇到这里结束。下篇讲——环境跑起来之后怎么看懂一个陌生 Django 项目的架构脉络。源码骑士 — 源码级拆解从底层看透技术关注跟博主一起从源码视角深耕底层原理❤️点赞让优质内容被更多人看见⭐收藏核心知识点存好随用随查评论分享你的经验或疑问一起交流一键四连别忘了给博主一键四连️寄语环境是地基地基打不好房子再漂亮也白搭。结语两天复现一个老项目环境不算慢——重要的是每一步都能定位问题。下篇进入代码层面——urls.py 路由树怎么读。一键四连