关于 Django Orm Lens
Django ORM Lens 通过静态解析为 Django 模型生成 ER 图、N+1 检测和迁移风险检查,无需启动 Django 或连接数据库。它提供 VS Code 扩展、命令行工具和 MCP 服务,面向编辑器、CI 与 AI 编码 Agent 的用户。
主要功能
- 01基于静态解析,无需数据库
- 02VS Code 侧边栏模型树与实时 ER 图
- 03N+1 查询检测与迁移风险检查
- 0418 条代码检查规则并附快速修复
- 05提供 CLI、SARIF 输出与 GitHub Action
适用场景
- 01在陌生的 Django 项目中快速了解模型关系
- 02在 CI 中阻止 N+1 查询与高风险迁移的合并
- 03让 AI Agent 通过 MCP 查询模式信息
MCP 相关
该项目提供可选的 MCP 服务,包含 13 个只读工具,供 AI Agent 查询 Django 模式信息,无需导入 Django 或启动应用。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
English · Русский · Español · 中文
Django ORM Lens
无需启动 Django,即可生成 ER 图、检测 N+1 并检查迁移风险。
整个模型图实时呈现在编辑器侧边栏中,为 CI 设置门禁,并通过 MCP 回答你的 AI Agent 的问题。所有信息均来自静态解析:无需数据库、无需 runserver,也无需可用的虚拟环境。
替代: graph_models + django-schema-graph + 手绘 ER 图 + grep 考古。
⚡ 10 秒获取第一个洞察
uvx django-orm-lens scan -f table # every app and model at a glance
uvx django-orm-lens nplusone # N+1 loops, with the select_related to add
uvx django-orm-lens migration-risk # migrations that lock tables or fail on existing rows
刚克隆的仓库、损坏的虚拟环境、没有 settings 模块——你仍然可以在终端中看到项目的每个应用和模型,以及其中的 N+1 循环和高风险迁移。(uvx 来自 uv;pipx run 的用法相同。)
然后选择使用方式——三种发行形式,共用一个解析器核心:
| 你的角色 | 安装方式 | 你将获得 |
|---|---|---|
| 编辑器用户 — VS Code / Cursor / Windsurf / VSCodium | code --install-extension frowningdev.django-orm-lens | .filter() 中的字段自动补全、侧边栏树、实时 ER 图、悬停卡片、18 条带 QuickFixes 的 lint 规则 |
| 终端 / CI 用户 | pip install django-orm-lens | 17 个子命令、SARIF + PR 注释、pre-commit hooks、GitHub Action |
| AI Agent 用户 — Cursor / Claude Code / Aider / Zed / Continue | pip install "django-orm-lens[mcp]" | 13 个只读 MCP 工具,基于真实数据回答架构问题 |
MCP 只需一个 JSON 配置块即可完成设置——请参阅集成。将 DJANGO_ORM_LENS_ROOT 指向 Django 项目的绝对路径。
🆓 付费档功能,免费且采用 MIT 许可
架构审查在几乎所有地方都属于付费类别。能够审查每个拉取请求的机器人、能追踪 QuerySet 超出其创建函数范围的分析、能捕获架构漂移的检查,以及基于真实表统计数据给出索引建议的工具——这些通常都需要按席位或数据库订阅才能使用。
这里提供了所有这些功能,采用 MIT 许可,没有档位限制、席位数量限制、账户要求或遥测:
| 通常作为付费档出售的功能 | 此处 |
|---|---|
| 用于架构变更的 PR 审查机器人——发布一次,然后原位更新 | blast-radius + Action |
| 能跨函数追踪 QuerySet 的分析 | nplusone |
| 架构漂移检测 | drift |
| 根据已观察到的 QuerySet 用法提出索引建议 | suggest-indexes |
| 根据真实表大小评估迁移风险 | blast-radius --stats |
| 破坏性迁移的影响范围 | blast-radius |
| 移除字段对跨层的影响 | impact |
没有 Pro 档,也没有推出计划。 如果这个工具为你省下一个下午,只需点个星标即可。
📊 使用情况
如果这个工具能在你下次接触陌生的 Django 项目时,帮你省去一次
grep,那就**点个星标,帮助更多人发现它**。
📈 Star 增长趋势
⚡ 安装
VS Code / Cursor / Windsurf(VS Code Marketplace):
code --install-extension frowningdev.django-orm-lens
VSCodium / code-server / Gitpod / 任何 OSS Code 分支(Open VSX):
codium --install-extension frowningdev.django-orm-lens
或者在扩展视图中搜索 Django ORM Lens —— 两个注册表中的发布者均为 frowningdev。
终端和 AI 编码 Agent:
pip install django-orm-lens # CLI only
pip install "django-orm-lens[mcp]" # + MCP server for AI agents
需要 Python 3.9+。CLI 无任何运行时依赖。
Docker(v0.6+):
docker run --rm -v "$PWD:/workspace" ghcr.io/frowningdev/django-orm-lens scan --path .
支持多架构(amd64 + arm64)。主机无需安装 Python。适用于 CI 和临时审计。
🎯 问题所在
离线可用。虚拟环境损坏时可用。在别人的笔记本电脑上可用。在 CI 中可用。
你打开一个 Django 项目,里面有 20 个应用。你需要回答一个简单的问题:
“
Order模型属于哪个应用?它与User有什么关联?”
如今,你得:按 Ctrl+P,搜索“models”,在 30 条结果中滚动,打开五个文件,按 Ctrl+F 搜索 class Order,阅读 400 行 ForeignKey('otherapp.Something') 字符串,还要努力回忆两份文件之前看到的内容。
每次都要耗掉半天。每个项目都是如此。
✨ 使用 Django ORM Lens
📚 一览无余的树形结构每个应用 → 每个模型 → 每个字段 → 每个 通过图标一眼区分 |
🕸️ 实时 ER 图一条命令即可打开整个架构的 Mermaid 实体关系图。编辑时,图表会随之重绘。可导出为 SVG。
|
🔎 悬停查看关联在任意 Python 文件中,将鼠标悬停在 |
🧭 跳转到定义点击树中的任意字段,光标便会定位到对应的行。可按应用或模型名称筛选树形结构。全面支持拆分的 |
⚡ 零配置无需设置 |
🎨 原生 VS Code 界面深色主题、浅色主题,或使用你自己的主题。遵循你的图标主题、字体和快捷键设置。不花哨,也不带品牌装饰。 |
🚀 强大功能
|
### 💥 影响范围
架构变更在审查时真正需要回答的问题是:会影响什么? 每个具有破坏性的迁移操作都会成为一个目标,并标注其风险、代码库中仍在读取它的位置,以及整个模型操作引发的级联影响。
|
🧭 架构漂移无需启动 Django 即可运行 Django 自带的检查需要可用的 settings 模块、可导入的应用注册表,以及所有依赖都已安装——在刚克隆的代码库或损坏的 venv 中无法满足,而这恰恰是最容易及时处理检查结果的时候。只有危险的情况会导致构建失败:声明了字段却从未迁移,意味着数据库中不会存在对应列,首次访问该列的查询就会报错。 |
🎯 内联诊断与 QuickFixes(18 条规则)对 使用 |
🧪 Factory 生成器右键单击任意模型 → 生成 也可通过每个模型类上方的 CodeLens 使用。 |
🕰 时间回溯架构差异选择一个 重命名会作为一等事件处理,绝不会拆成 |
🔎 影响分析“如果我删除这个字段,会有什么问题?”——右键单击字段或模型 → 扫描整个工作区,并按 Django 层分组显示结果(models、serializers、forms、admin、views、urls、templates、tests、migrations)。 结果带有 确定 / 可能 / 或许 置信度标签。支持 ORM 字符串引用( |
⚡ 交互式查询构建器右键单击字段或模型 → 选择模板 → 将代码片段插入光标处(带制表位),或插入新的未命名缓冲区。 在 FK 上使用 |
🎨 侧边栏体验全面升级稳定的
|
## 📸 效果展示
实时示例 — 真实的 django-orm-lens er 输出,由 GitHub 在此处渲染:
erDiagram
User {
CharField display_name
}
Tag {
CharField name
}
Post {
CharField title
DateTimeField created_at
}
Comment {
TextField body
}
Post }o--|| User : "author [CASCADE, as posts]"
Post }o--o{ Tag : "tags [as posts]"
Comment }o--|| Post : "post [CASCADE, as comments]"
Comment }o--|| User : "author [SET_NULL]"
扩展还包含:
- 🕸️ 实时 ER 图 — Mermaid 基数箭头、边标签(
CASCADE、through Model、as related_name)、主题感知,一键导出 SVG - 🔎 悬停卡片 — 悬停在任意
ForeignKey('app.Model')或ManyToManyField(...)上即可查看,并提供一键跳转链接 - 🧭 CodeLens — 每个
class Model行上方都会显示字段数、关系数,以及 打开 ER 图 操作 - 🎨 命名主题 — 用于图表 Webview 的
auto/default/dark/forest/neutral
🤖 面向终端和 AI 编码 Agent
为 VS Code 扩展提供支持的同一解析器也以独立 Python 包的形式提供 — 可选配 MCP(Model Context Protocol)服务,让任何兼容 MCP 的 AI Agent 都能浏览 Django 架构,无需导入 Django 或启动应用。
CLI
django-orm-lens scan -f json # every app, every model, every field
django-orm-lens describe blog.Post # one model in Markdown
django-orm-lens list | fzf # flat app.Model — pipes anywhere
django-orm-lens er > schema.mmd # ER diagram — Mermaid (default)
django-orm-lens er -f dbml > schema.dbml # …or DBML: paste into dbdiagram.io
django-orm-lens er -f d2 > schema.d2 # …or D2 / plantuml / dot
django-orm-lens diff before.json after.json # what a PR changes structurally
django-orm-lens nplusone --format github # N+1 findings as PR annotations
django-orm-lens migration-risk -f sarif # SARIF for GitHub Code Scanning
django-orm-lens suggest-indexes blog.Post # Meta.indexes proposals from usage
django-orm-lens signals # sender→signal→handler graph
django-orm-lens migration-deps blog -f mermaid # per-app migration DAG
django-orm-lens cascade blog.Author # what one delete() takes down
django-orm-lens impact author # what still references a field
django-orm-lens blast-radius -f markdown # risks + who still reads them
django-orm-lens drift # migrations vs models, no boot
django-orm-lens stats-sql # read-only SQL for --stats
impact、blast-radius、drift和stats-sql随 py-1.7.0 及更高版本发布。
每条命令都接受 --path <dir> 和 --exclude <glob>。如果 nplusone / migration-risk / diff 发现问题,退出代码为 1 — 可将它们加入 CI,在出现回归时阻止 PR。
MCP 服务
只需向 Agent 注册一次,即可提供 13 个只读工具:
| 工具 | 用途 |
|---|---|
list_apps | 工作区中的所有 Django 应用及其模型数量 |
list_models | 扁平的 app.Model 列表,可选按应用筛选 |
describe_model | 单个模型的完整字段 / 关系 / Meta 详情 |
find_relations | 单个模型的入站和出站关系 |
cascade_preview | 单次 delete() 的影响范围,按 on_delete 分组 |
er_diagram | ER 图 — mermaid / dbml / d2 / plantuml / dot |
describe_migration_dependency | 按应用划分的迁移 DAG:根节点、叶节点、跨应用依赖 |
suggest_indexes | 根据观察到的 QuerySet 用法提出 Meta.indexes 建议 |
signal_graph | 根据 @receiver 装饰器生成发送者→信号→处理器图 |
blast_radius | 破坏性迁移的影响:风险、仍在读取相关内容的代码,以及级联影响 |
drift | 无需启动 Django 即可执行 makemigrations --check — 将迁移与 models.py 进行比较 |
impact | 字段或模型名称的所有引用,按 Django 层分组 |
nplusone_scan | 扫描整个工作区中的静态 N+1 问题 |
# Start it directly
django-orm-lens-mcp
# Or via the CLI subcommand
django-orm-lens mcp
工作区解析(py-1.3.0+)。 每个工具调用都接受可选的
workspace_root 参数。解析优先级:显式参数 →
$DJANGO_ORM_LENS_ROOT → 当前工作目录。无效或非 Django
路径会返回结构化封装
({"error": "WORKSPACE_NOT_DJANGO", "hint": "…"}),而不是空结果,
以便 Agent 自行纠正。可选沙箱设置:
DJANGO_ORM_LENS_ALLOWED_ROOTS(Windows 上用 ; 分隔,其他平台用 : 分隔)。
Agent 技能
工具告诉 Agent 哪些内容是事实;技能则告诉它如何运用这些信息。
skills/django-orm-lens 是一个 SKILL.md
包,内含迁移审查、安全重命名和移除、N+1 修复与级联检查的操作指南,为 16 条迁移规则分别提供安全改写方案,以及用于一次性判定结果(BLOCK / FIX BEFORE DEPLOY /
SHIP)的 audit.py。连接后会使用 MCP 服务,否则会通过
uvx 回退到 CLI。
- 从 Agensi 安装(免费),或
- 将文件夹复制到 Agent 的技能目录中,例如 Claude Code:
git clone --depth 1 https://github.com/FROWNINGdev/django-orm-lens
cp -r django-orm-lens/skills/django-orm-lens ~/.claude/skills/
## 🛡️ 为 CI 设置拦截
在架构回归问题进入 PR 时立即发现,成本最低。有 4 种零配置方式可以拦截:
影响范围 PR 机器人——将完整的架构审查整合为一条评论,并在每次推送时就地更新,而不是每次都新增评论:
name: Schema review
on: pull_request
permissions:
contents: read
pull-requests: write # only for `comment: true`
jobs:
blast-radius:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: FROWNINGdev/django-orm-lens@action-v1
with:
command: blast-radius
only-changed: true # scope to migrations this PR touches
comment: true # post once, then update in place
github-token: ${{ github.token }}
评论会在作业失败之前发布,因此即使 PR 被拦截,也会说明原因。only-changed 通过 API 读取 PR 的文件列表,而非使用 git diff,因为 actions/checkout 默认采用 fetch-depth: 1,本地历史中不包含基准提交。在 push 事件中,这两个标志都会跳过并显示提示,而不是导致失败,因此一个工作流即可覆盖这两种触发方式。
该 Action 从 PyPI 安装,因此
blast-radius和drift需要 py-1.7.0 或更高版本——如果工作流不能使用浮动版本,请用version: 1.7.0固定版本。若要改用尚未发布的构建,请添加install: false并自行安装源代码;本仓库自己的工作流正是这样做的,也借此在每个 PR 上验证该 Action。
pre-commit——两个钩子,本地无需安装任何东西:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/FROWNINGdev/django-orm-lens
rev: py-v1.13.5
hooks:
- id: django-orm-lens-nplusone
- id: django-orm-lens-migration-risk
GitHub Action——发现的问题会显示为 PR 注释,无需额外权限:
- uses: FROWNINGdev/django-orm-lens@action-v1
with:
command: migration-risk # or: nplusone
format: github # ::error / ::warning annotations on the diff
SARIF → Code Scanning——发现的问题会显示在仓库的 Security 标签页中:
- run: |
pip install django-orm-lens
django-orm-lens migration-risk --format sarif --exit-zero > lens.sarif
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: lens.sarif
退出码适用于 CI:发现问题时,diff 和 nplusone 以 1 退出;发现严重问题时,migration-risk 和 blast-radius 以 1 退出;当字段已声明但从未迁移时,drift 以 1 退出。添加 --exit-zero 可启用仅报告模式。
🔌 集成
| 客户端 | 启用方法 | 状态 |
|---|---|---|
| VS Code | code --install-extension frowningdev.django-orm-lens | ✅ |
| Cursor | 同一 VSIX + 可选的 MCP 条目,位于 ~/.cursor/mcp.json | ✅ |
| Windsurf / VSCodium / 任意 Code 分支版本 | 从 Marketplace 或 GitHub Releases 安装 VSIX | ✅ |
| Aider | 将 django-orm-lens-mcp 添加到 mcp.json | ✅(通过 MCP) |
| Continue.dev | 在 ~/.continue/config.json 中注册 MCP 服务 | ✅(通过 MCP) |
| Zed | 在 Zed 设置中注册 MCP 服务 | ✅(通过 MCP) |
| 任意兼容 MCP 的客户端 | 将 command 指向 django-orm-lens-mcp,设置 DJANGO_ORM_LENS_ROOT | ✅ |
| pre-commit | repo: https://github.com/FROWNINGdev/django-orm-lens + 两个钩子 ID | ✅ |
| GitHub Actions | uses: FROWNINGdev/django-orm-lens@action-v1 — 注释或 SARIF | ✅ |
| 可通过 MCP Registry 发现 | 官方 Model Context Protocol 服务目录 | ✅ |
| 普通终端 / CI | pip install django-orm-lens && django-orm-lens scan | ✅ |
示例:Cursor / 任意 MCP 客户端
{
"mcpServers": {
"django-orm-lens": {
"command": "django-orm-lens-mcp",
"env": { "DJANGO_ORM_LENS_ROOT": "/abs/path/to/your/project" }
}
}
}
⚡ 性能
回归测试套件会解析 Zulip、Saleor、Wagtail、django CMS 和 Mezzanine 中随附的模型图——涵盖 13,478 行真实项目的 models.py 中的 59 个模型——在笔记本电脑上端到端耗时约 20 ms(在仓库的黄金测试样本集上,3 次运行中的最佳成绩为 21 ms;CI 会在每个矩阵单元中运行 <2 s 的保护检查)。
你可以自行复现:
git clone https://github.com/FROWNINGdev/django-orm-lens && cd django-orm-lens/cli
pip install -e . && python -m pytest tests/test_golden_fixtures.py tests/test_golden_snapshots.py -q
🎯 适用人群
- Django 开发者:加入拥有 10 个以上应用的代码库,却被
models.py的大量文件搞得无从下手。 - 合同 / 自由职业工程师:需要在第一个小时而非第一周内理解陌生的 Django 项目。
- 团队新员工培训:希望一眼查看架构,而无需搭建文档基础设施。
- AI Agent 高阶用户(Cursor / Aider / Zed / Continue / 任意兼容 MCP 的客户端):需要 Agent 准确回答架构问题,又不想提供数据库凭据或启动 Django。
- CI 流水线:验证架构形状(例如“我们是否意外破坏了
related_name?”),无需导入项目。 - 独立开发者:虚拟环境损坏或只能使用别人的笔记本时,无需
runserver,无需manage.py migrate,仍可正常运行。
## 🗺️ 市场定位
Django ORM Lens 处于编辑器工具和AI Agent 工具的交汇点——目前没有其他软件包覆盖这一领域:
| 细分领域 | 现有选项 | 代价 |
|---|---|---|
| 启动并生成关系图 | django-extensions graph_models | 需要 Graphviz、Django 设置和可用的数据库 URL |
| 基于 Web 的查看器 | django-schema-graph | 需要运行中的 Django 服务;又多了一个可能出问题的组件 |
| 管理面板 | Django Admin | 需要 runserver、身份验证和数据库——适合处理数据,不适合查看架构 |
| 编辑器插件 | PyCharm 的 Django Structure | 仅限 PyCharm;没有 CLI,也不支持 AI Agent |
| MCP 服务 | (此前没有) | AI Agent 只能从源代码猜测架构,结果并不完美 |
Django ORM Lens 是唯一一个通过同一解析器提供三种使用方式的工具: VS Code 扩展(适用于任何 Code 分支)、零依赖 CLI(适用于终端和 CI)以及 MCP 服务(适用于 AI Agent)。全部基于静态分析。全部免费。全部采用 MIT 许可证。
🤔 有何不同?
| Django ORM Lens | django-extensions graph_models | django-schema-graph | Django Admin | PyCharm Django Structure | |
|---|---|---|---|---|---|
| 无需可启动的 Django 项目即可运行 | ✅ | ❌ | ❌ | ❌ | ⚠️ |
| 零安装(无需 graphviz 或服务) | ✅ | ❌ | ❌ | ❌ | ❌(需要 PyCharm) |
| 可在 VS Code / Cursor / 任何 Code 分支中运行 | ✅ | ❌ | ❌ | ❌ | ❌ |
| 编辑器内的侧边栏树状视图 | ✅ | ❌ | ❌ | ❌ | ✅ |
| 实时 ER 图 | ✅ | ✅ | ✅ | ❌ | ❌ |
ForeignKey 悬停卡片 | ✅ | ❌ | ❌ | ❌ | ⚠️ |
| 模型类上的 CodeLens | ✅ | ❌ | ❌ | ❌ | ❌ |
支持拆分的 models/ 包 | ✅ | ⚠️ | ⚠️ | ✅ | ✅ |
| 适用于终端 / CI 的 CLI | ✅ | ⚠️ | ❌ | ❌ | ❌ |
| 适用于 AI Agent 的 MCP 服务 | ✅ | ❌ | ❌ | ❌ | ❌ |
| 可在 MCP Registry 中找到 | ✅ | ❌ | ❌ | ❌ | ❌ |
| 免费且开源(MIT) | ✅ | ✅ | ✅ | ✅ | ❌(付费 IDE) |
| Django 版本支持 | 4.0 – 5.2 | 最新版 | 3.2 – 4.1(自 2023 年起未更新) | 最新版 | 最新版 |
django-schema-graph自 2023-05 起未更新,也未对 Django 5.x 进行测试。
何时选择其他工具
明确说明适用范围:分析实时请求 → django-debug-toolbar。分析历史请求 → django-silk。在测试套件中断言查询次数 → django-perf-rec。对真实流量进行生产环境 APM 监控 → Scout / Sentry。Django ORM Lens 有意保持静态分析——它能在应用甚至还无法启动之前就发挥作用,也是唯一一个能在任何代码检出版本上供 CI 和 AI Agent 使用的工具。
⚙️ 配置
默认设置经过审慎选择,适用于大多数场景。如需调整:
// .vscode/settings.json
{
"djangoOrmLens.excludeGlobs": [
"**/migrations/**",
"**/node_modules/**",
"**/venv/**",
"**/.venv/**",
"**/env/**"
],
"djangoOrmLens.autoRefresh": true
}
| 设置 | 类型 | 默认值 | 作用 |
|---|---|---|---|
djangoOrmLens.excludeGlobs | string[] | 见上文 | 扫描时跳过的 Glob 模式 |
djangoOrmLens.autoRefresh | boolean | true | 在 models.py 发生变化时重新扫描 |
djangoOrmLens.codeFixes.enabled | boolean | true | DOL### 诊断和 QuickFixes 的总开关 |
djangoOrmLens.rules | object | {} | 按规则设置严重级别:{ "DOL007": "off", "DOL013": "error" } |
djangoOrmLens.rulesSelect | string[] | [] | Ruff 风格的选择设置。["DOL0"] 仅运行查询集和模型规则 |
djangoOrmLens.rulesIgnore | string[] | [] | Ruff 风格的忽略设置。["DOL03"] 禁用表单和视图规则 |
## 🔬 规则目录
18 项编辑器端检查(DOL001–DOL041),采用 Ruff 风格的代码、逐规则严重性等级和 Clippy 风格的适用性;此外还有 16 项 CLI 端迁移风险规则和静态 N+1 分析器。现在,每条规则都有自己的文档页面。
| 类别 | 规则 | 示例 |
|---|---|---|
| 查询集 | DOL001–DOL007 | .count() > 0 → .exists(),循环中的 FK 访问(N+1) |
| 模型定义 | DOL011–DOL015 | ForeignKey 未设置 on_delete,字符串字段设置 null=True |
| 日期时间 | DOL021–DOL022 | datetime.now() → timezone.now() |
| 表单 / 视图 | DOL031–DOL032 | 在 render() 中使用 locals(),Meta.fields = '__all__' |
| 原始 SQL | DOL041 | 在应用代码中覆盖 SET enable_hashjoin = off、plan_cache_mode、jit |
| 迁移风险 | 16 条规则 | 添加 NOT NULL 字段但未设置默认值、会锁表的索引构建、不可逆的数据迁移 |
| 静态 N+1 | 1 个分析器 | 循环中访问 FK/M2M,但未使用 select_related / prefetch_related |
→ 完整规则参考 — 每个代码都包含错误 / 正确示例、QuickFix 行为和抑制语法。
行内抑制
# django-orm-lens-disable-next-line DOL007
for user in User.objects.all():
print(user.profile) # not flagged
qs.count() > 0 # django-orm-lens-disable-line DOL001
# django-orm-lens-disable DOL011 ← on its own line, kills DOL011 for the rest of the file
适用性遵循 Rust 的 Clippy:safe 修复可自动应用(“Fix All”),suggestion 修复会作为 QuickFix 提供,但需经过审核;unsafe 发现永远不会自动应用。修复与分析器分离(采用 Roslyn 风格),因此单条规则可以随时间增加多个修复器,而无需改动检测逻辑。
🧭 命令
打开命令面板(Ctrl+Shift+P / Cmd+Shift+P),输入 “Django ORM Lens”:
| 命令 | 功能 |
|---|---|
Django ORM Lens: Refresh | 强制重新扫描工作区 |
Django ORM Lens: Show ER Diagram | 并排打开 Mermaid ER 图 |
Django ORM Lens: Filter Models | 按应用 / 模型 / 字段名称筛选树 |
Django ORM Lens: Clear Filter | 恢复完整的树 |
Django ORM Lens: Jump to Model | 程序化命令 — 由树中的点击和悬停卡片触发 |
Django ORM Lens: Find Reverse References | 右键单击模型 — 使用 QuickPick 列出所有指向该模型的 FK |
Django ORM Lens: Generate factory_boy Factory | 右键单击模型或使用 CodeLens — 搭建 DjangoModelFactory |
Django ORM Lens: Schema Diff (Time-Travel) | 选择两次提交 — 获取以 markdown 缓冲区呈现的类型化差异 |
Django ORM Lens: Find Impact (What Uses This?) | 右键单击字段或模型 — 扫描整个工作区的引用 |
Django ORM Lens: Build Query (Insert Snippet) | 右键单击字段或模型 — 选择 ORM 模板 |
🗺️ 路线图
已发布
- 按应用分组的侧边栏树
- 实时 Mermaid ER 图
- 将鼠标悬停在
ForeignKey('app.Model')上时显示卡片 - 按名称筛选树
- 支持拆分的
models/包 - 将 ER 图导出为 SVG
- 面向终端和 AI Agent 的 Python CLI + MCP 服务
- 为空工作区提供欢迎视图
- 路径安全的跳转到定义和经过清理的悬停 Markdown
- v0.3.0 — 每个模型类上方显示 CodeLens(
N fields · N relations · Open ER diagram) - v0.3.0 — 图表上的边标签(
CASCADE、SET_NULL、PROTECT、related_name) - v0.3.0 — 命名颜色主题(
auto/default/dark/forest/neutral) - v0.3.1 — M2M 边上的
through_model(由 @kingrubic 贡献) - v0.3.1 — 已列入 官方 MCP 注册表 + Glama.ai
- v0.6.0 — CLI
nplusone— 静态 N+1 检测器(在循环中访问 FK/M2M,但未使用select_related/prefetch_related) - v0.6.0 — CLI
migration-risk— 标记migrations/*.py中的风险操作(目前有 15 条规则) - v0.6.0 — CLI
diff— 比较两个 schema JSON 转储,以便审查 PR - v0.6.0 — ER 图缩略图按 Django 应用对节点进行颜色编码
- v0.6.0 — README 翻译:🇷🇺 俄语、🇪🇸 西班牙语、🇨🇳 中文
- v0.6.0 — GHCR 上的 Docker 镜像:
docker run ghcr.io/frowningdev/django-orm-lens - v0.7.0 —
settings.AUTH_USER_MODEL在所有位置均可解析:N+1 反向关系、信号发送方、Mermaid ER、VS Code webview、入站关系面板、React ER - v0.7.0 — 基于 AST 的字段解析器:
ForeignKey(on_delete=CASCADE, to='User')无论关键字参数顺序如何均可解析(Python + TS 保持一致) - v0.7.0 — 公开的共享辅助函数:
find_user_model、resolve_related_tail、find_model、iter_workspace_py_files(Python)+findUserModel、resolveRelatedTail(TS) - v0.7.0 —
--verbose不再遍历两次目录树;WorkspaceIndex.scanned_files提供文件数量 - v0.7.3 — 现在可以解析字段上的 PEP-526 类型注解(
jti: CharField[str] = models.CharField(...))——由 @jsabater 报告(#25),并提供了简洁的 Django Ninja 1.6 复现示例 - v0.7.4 — PEP-695 泛型类头(Python 3.12+):现在可以解析
class Container[T](models.Model): - v0.7.5 — 现在可以检测别名模型模块(
from django.db import models as m)和第三方字段包(jsonfield.JSONField) - v0.7.6 — 现在可以解析使用制表符缩进的模型主体(默认使用制表符的编辑器不再显示空模型)
- v0.8.0 — 内联 QuickFixes:16 条规则(
DOL001..DOL032),支持按规则设置严重级别 + Ruff 风格的 select/ignore + 内联# django-orm-lens-disable-next-line - v0.8.0 — 工厂生成器:从任意模型生成
factory_boy脚手架,并按字段类型选择 Faker 提供器 - v0.8.0 — 时间旅行 Schema 差异:选择两个提交 → 生成带类型的 Markdown 差异,并原生支持重命名检测
- v0.8.0 — 影响分析:在整个工作区的每个 Django 层中扫描字段引用,并标注 Certain/Likely/Possibly 置信度
- v0.8.0 — 交互式查询构建器:右键 → 选择模板 → 在光标处插入代码片段;支持语法感知(FK 使用
.select_related,遵循related_name) - v0.8.0 — 侧边栏 UX 全面改进:稳定的
TreeItem.id、带command:深层链接的MarkdownString工具提示、FileDecorationProvider徽标、活动栏上的TreeView.badge、三种由 when 条件控制的viewsWelcome状态
v1.5.0 — “一个核心,三个界面”浪潮
- CI 格式:SARIF 2.1.0,以及通过
--format github为nplusone和migration-risk添加 PR 注释 - 四个分析器从仅支持 MCP 扩展到 CLI:
suggest-indexes、signals、migration-deps、cascade -
er --format dbml | d2 | plantuml | dot— 符合社区标准的图表导出格式(dbdiagram.io、D2、PlantUML、Graphviz —dot由 @JJordan0C 贡献) - 新增三个 migration-risk 规则:
runpython_no_reverse、alter_unique_together_lock、alter_index_together_deprecated— 共 15 条 - pre-commit 钩子(
django-orm-lens-nplusone、django-orm-lens-migration-risk)+ 组合式 GitHub Action -
docs/rules/— 为每条规则提供一个文档页面(共 19 页) - 针对 59 个真实模型的黄金快照回归测试套件(Zulip / Saleor / Wagtail / django CMS / Mezzanine);ruff + mypy 现在会阻止 CI 通过
- 迁移依赖图 —
migration-deps(text / json / mermaid)
py-1.7 → 1.8 — 架构智能升级
-
blast-radius— 将迁移风险与仍在读取受影响架构的代码关联起来,并作为 PR 机器人运行(comment: true、置顶、only-changed) -
drift— 无需启动 Django 即可运行makemigrations --check -
impact <name>— 查看仍引用某个模型或字段的代码,并按 Django 层分组 -
blast-radius --stats+stats-sql— 可选提供生产环境行数统计,SQL 只读且由你自行运行(该工具不会持有数据库凭据) -
nplusone可跨函数追踪 — 会继续追踪辅助函数返回的 queryset,找到使用它的循环 - 将
blast_radius、drift和impact作为 MCP 工具公开 — 为 AI Agent 提供 13 个工具 -
drift在报告和--help中说明其!!/~标记 — 由 @sevdog 报告(#57) -
drift会追踪抽象基类的继承关系 — 按照 Django 的处理方式,抽象基类的字段会计入具体子类自身字段 — 由 @sevdog 报告(#58) -
suggest-index能识别 Django 已创建的索引 — 主键(pk和id属于同一次查找)、db_index、unique、外键、unique_together、UniqueConstraint— 由 @sevdog 报告(#60),@RinZ27 也独立发现了相同原因(#61) - 新增第六个黄金测试样例 — Read the Docs 加入 Zulip、Saleor、Wagtail、django-CMS 和 Mezzanine,使解析器覆盖 75 个模型和 538 个真实 Django 字段 — 由 @JJordan0C 贡献(#62,关闭 #51)
- django-taggit
TaggableManager按照其 M2M 关系解析 — 通过taggit.TaggedItem关联到taggit.Tag,并遵循through=覆盖设置;Python 和 TypeScript 解析器均适用 — 由 @Guflly 贡献(#63,关闭 #50) -
DOL021正确说明USE_TZ默认值 — Django 4.2 及之前为False,从 5.0 起为True;同时指出startproject模板自 4.0 起设置USE_TZ = True,这是另一回事 — @Justine0211 翻译页面时发现了此问题(#52) -
parity_input.py测试样例现在包含真实models.py应有的models导入 — 由 @RinZ27 贡献(#64)
py-1.9 → 1.12 — 真实代码库检查升级 通过 CLI 在 django-oscar、django-guardian、django-allauth 和 django-cms 的实际检出目录上运行后发现,而非使用测试夹具。这些问题在绿色测试套件中全都不可见,其中两个还会让工具信心十足地给出错误答案。
- 解析模块级代码块中声明的模型——可插拔 Django 框架都会使用可交换模型惯用写法(
if not is_model_registered(...):后接缩进的class),这与以^class为起点的类发现方式相悖。django-oscar 的模型数从 12 个增至 82 个,此前这 12 个全都来自各自的tests/目录。全部 6 个黄金快照均保持字节级不变:第 0 列的类仍按原样解析 - 与
models.py一并读取abstract_models.py——可插拔框架会将抽象基类放在这里,而models.py中只保留具体子类,因此 django-oscar 的 83 个模型中有 72 个报告字段数为零。现在只剩 8 个,而且这 8 个都是正确的:它们继承具体模型,而多表继承会将列留在父模型的表中 -
drift不再因两个应用目录同名而导致构建失败——按应用名称合并重放后的迁移状态,与声明侧已有的键控方式一致。在 django-guardian 的实际检出目录中,阻塞数量从 1 降至 0,矛盾的重复行也随之消失,同时真正尚未迁移的字段仍会阻塞 - django-mptt 模型不再不可见——
MPTTModel现已被识别为基类,TreeForeignKey/TreeOneToOneField/TreeManyToManyField会按其所继承的 Django 字段进行报告,因此TreeForeignKey('self', ...)绘制的自关联边与普通ForeignKey('self', ...)完全一致。不添加django-mptt依赖——即使虚拟环境已损坏,解析器仍能正常工作。黄金快照现已包含 Saleor 的product.Category及其children关联边:新增 76 行,没有删除任何行(关闭 #49) - MCP 服务会报告自身版本——
FastMCP不会转发任何版本信息,因此 SDK 会退而使用importlib.metadata.version("mcp"),导致每个initialize响应都向客户端报告错误项目的发布版本号
v0.9 → v0.12.1 — 扩展插件终于跟上了
- v0.9.0 — 时间旅行架构差异中的
UniqueConstraint部分跟踪:将add/drop/change/rename作为类型化事件处理,并通过fromCondition携带变更前的谓词,以便审查评论能够显示Q(is_primary=True) → Q(is_primary=True, deleted=False);重命名也不再显示为有信息损失的add + drop组合。同一模型上的多个未命名约束会分别映射到#anon-<index>,而不是合并成单个事件。此功能受 django-extensions #1813 启发:sqldiff会丢弃condition=谓词,导致迁移审查者始终看不到具体变更 - v0.10.0 — 影响分析的层级检测改为基于工作区相对路径运行。此前,它会在文件的绝对路径中的任意位置匹配
/tests/和/views.py,因此,如果项目检出到任何名为tests的目录下,或单体仓库中项目上方包含services/tests/,所有文件都会被报告为该层级,views.py会被识别为测试文件,admin.py也会被识别为测试文件。此外:Webview 消息现在按来源而非源对象进行验证,并会检测相互冲突的末端迁移——两个迁移声明了同一个父迁移,而 Django 只有在migrate时才会报错 - v0.10.1 — Marketplace 列表介绍了影响分析、影响范围和架构漂移,并明确说明该工具免费且采用 MIT 许可,没有 Pro 版本。商店页面仍将扩展描述为侧边栏和 ER 图——那是两个迭代周期前的功能——因此搜索这些功能的人都找不到它。元数据只有在发布后才会生效,这就是它需要单独发布的原因
- v0.11.0 — django-mptt 支持的 TypeScript 部分单独发布,而非并入后续版本:从 py-1.12.0 发布到此版本构建完成期间,CLI 和扩展对 django-mptt 架构的理解并不一致;这正是共享黄金测试样例旨在防止的问题
- v0.12.0 — 扩展会在用户第三次主动打开 ER 图时请求 GitHub Star,而不是在安装时请求:工具还没做任何事就弹出提示,很容易被用户条件反射式地忽略,而且用户心里会认为这种忽略是永久的。重新渲染已打开面板的侧边栏刷新不会计入次数——这并非用户主动请求查看内容。“稍后”和“不要再询问”会保存为不同状态,因此选择稍后会在 12 次打开后恰好重新触发一次请求;用户一生最多会看到两次提示。这项策略是纯函数,由 6 个无需 VS Code 宿主的测试覆盖
- v0.12.1 — 导出为 SVG 会生成无法打开的文件。
toSvg返回百分号编码的标记,而toPng返回 Base64;保存路径会假定所有以data:开头的数据都是 Base64,而对百分号编码文本进行 Base64 解码不会报错——解码器会静默丢弃所有不属于其字符集的字符,并返回字节。一个 48 个字符的<svg>文档以正确的名称和看似合理的大小写入磁盘,内容却完全无效。现在会从数据 URL 的标头读取传输编码,而不是根据前缀猜测
下一步
- v0.13.0 — 在
.filter()/.exclude()/.get()中补全字段(#3) - v0.10.0 — 应用 / 模型切换复选框:在侧边栏取消勾选应用或模型,即可将其从 ER 图中移除
- 将 DOL 规则引擎移植到 Python CLI——一套规则目录,三个使用入口
后续计划
- 第三方字段支持——
django-model-utils(django-taggit已在 py-1.11.0 中发布,django-mptt已在 py-1.12.0 / v0.11.0 中发布) - JetBrains / PyCharm 插件(如果有需求)
为相应的议题点 👍 投票。
## ❓ 常见问题
你们会把我的任何代码发送到服务器吗?
不会。每个字节都留在你的设备上。解析器使用纯 TypeScript(扩展)或纯 Python(CLI)实现。不会调用大模型,不会进行遥测、分析或错误报告。Mermaid 渲染器运行在 VS Code 的 Webview 沙盒中。
它支持 Poetry / uv / conda / 完全不使用虚拟环境吗?
支持。扩展会直接读取 Python 源代码——不会导入 Django,也不关心你使用哪种包管理器。CLI 需要 Python 3.9+,仅此而已。
我的模型分散在 models/ 包中的多个文件里。也能正常工作吗?
可以,从 v0.2.0 起就支持。扩展和 CLI 都会扫描
models/*.py,同时也会扫描传统的 models.py。
我可以将它与 DRF serializers、Wagtail、Oscar 或第三方基础模型搭配使用吗?
任何看起来像 Django 模型的类都会被识别:
models.Model 的子类、以 Abstract 开头的抽象基类、以 Mixin 结尾的常见混入类,以及 TimeStampedModel 或 PolymorphicModel 等已知基础类名称。非模型类(ModelAdmin、ModelSerializer、Form、View、Manager 等)会被过滤掉。
哪些 AI Agent 可以使用 MCP 服务?
任何兼容 MCP 的客户端都可以——Cursor、Aider、Continue.dev、Zed,以及任何其他支持该协议的工具。只需将
command 指向已安装的 django-orm-lens-mcp 二进制文件。请参阅集成部分。
如何在 CI 中阻止架构回归?
有三种无需配置的方式:两个 pre-commit 钩子、复合 GitHub Action(在 PR 注释中显示结果时使用
uses: FROWNINGdev/django-orm-lens@action-v1 和 format: github),或将 --format sarif 的输出传入 github/codeql-action/upload-sarif,以便在 Security 选项卡中查看。diff / nplusone 在发现问题时以状态码 1 退出,migration-risk 在发现严重问题时以状态码 1 退出。
有 JetBrains / PyCharm 版本吗?
目前还没有。PyCharm 的 Django Structure 工具窗口已经很好用了,因此新增价值有限。如果有足够多的人提出需求,再开发才值得。
🆘 支持
- 🐛 问题报告 — GitHub Issues(请附上精简的
models.py代码片段) - 💡 功能请求 / 想法 — GitHub Discussions
- 📝 市场评价 — 为扩展评分(这是推动项目持续发展的最快反馈方式)
- 🐍 PyPI 页面 — pypi.org/project/django-orm-lens
- 💚 赞助 — github.com/sponsors/FROWNINGdev
📜 许可证
MIT © FROWNINGdev
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。