mcpField
D
Django Orm Lens

Django Orm Lens

本地服务
marketplace.visualstudio.com开发工具94今天更新

关于 Django Orm Lens

Django ORM Lens 通过静态解析为 Django 模型生成 ER 图、N+1 检测和迁移风险检查,无需启动 Django 或连接数据库。它提供 VS Code 扩展、命令行工具和 MCP 服务,面向编辑器、CI 与 AI 编码 Agent 的用户。

主要功能

  1. 01基于静态解析,无需数据库
  2. 02VS Code 侧边栏模型树与实时 ER 图
  3. 03N+1 查询检测与迁移风险检查
  4. 0418 条代码检查规则并附快速修复
  5. 05提供 CLI、SARIF 输出与 GitHub Action

适用场景

  1. 01在陌生的 Django 项目中快速了解模型关系
  2. 02在 CI 中阻止 N+1 查询与高风险迁移的合并
  3. 03让 AI Agent 通过 MCP 查询模式信息

MCP 相关

该项目提供可选的 MCP 服务,包含 13 个只读工具,供 AI Agent 查询 Django 模式信息,无需导入 Django 或启动应用。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"django-orm-lens": {
"command": "uvx",
"args": [
"django-orm-lens"
]
}
}
}
启动命令uvx django-orm-lens

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypidjango-orm-lens1.13.6

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

English · Русский · Español · 中文

Django ORM Lens — 为 Django 模型提供实时侧边栏和 ER 图

Django ORM Lens

无需启动 Django,即可生成 ER 图、检测 N+1 并检查迁移风险。

整个模型图实时呈现在编辑器侧边栏中,为 CI 设置门禁,并通过 MCP 回答你的 AI Agent 的问题。所有信息均来自静态解析:无需数据库、无需 runserver,也无需可用的虚拟环境。

替代: graph_models + django-schema-graph + 手绘 ER 图 + grep 考古。


PyPI Python Django versions CI Downloads License


Install on VS Code Install on Open VSX Docker GHCR


入选 Django News #347 · PyCoder's Weekly #746


⚡ 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 / VSCodiumcode --install-extension frowningdev.django-orm-lens.filter() 中的字段自动补全、侧边栏树、实时 ER 图、悬停卡片、18 条带 QuickFixes 的 lint 规则
终端 / CI 用户pip install django-orm-lens17 个子命令、SARIF + PR 注释、pre-commit hooks、GitHub Action
AI Agent 用户 — Cursor / Claude Code / Aider / Zed / Continuepip 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 档,也没有推出计划。 如果这个工具为你省下一个下午,只需点个星标即可。

📊 使用情况

GitHub stars Forks Contributors PyPI monthly Total downloads Open VSX downloads VS Code installs Marketplace rating Last commit


MCP Registry Smithery Glama awesome-mcp-servers mcp.so

如果这个工具能在你下次接触陌生的 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

📚 一览无余的树形结构

每个应用 → 每个模型 → 每个字段 → 每个 Meta 选项。按应用分组,按字母顺序排序,可展开。

通过图标一眼区分 CharField、ForeignKey 和 ManyToManyField。

🕸️ 实时 ER 图

一条命令即可打开整个架构的 Mermaid 实体关系图。编辑时,图表会随之重绘。可导出为 SVG。

ForeignKey、OneToOneField 和 ManyToManyField 会显示为规范的基数箭头。

🔎 悬停查看关联

在任意 Python 文件中,将鼠标悬停在 ForeignKey('app.Model') 上,即会弹出卡片,显示目标模型的字段和关联,并提供“跳转到”链接。无需按 Ctrl+F,也无需打开文件对话框。

🧭 跳转到定义

点击树中的任意字段,光标便会定位到对应的行。可按应用或模型名称筛选树形结构。全面支持拆分的 models/ 包。

⚡ 零配置

无需设置 DJANGO_SETTINGS_MODULE。无需运行 runserver。静态解析 models.py。虚拟环境损坏、缺少依赖或使用别人的笔记本电脑时都能正常工作。

🎨 原生 VS Code 界面

深色主题、浅色主题,或使用你自己的主题。遵循你的图标主题、字体和快捷键设置。不花哨,也不带品牌装饰。


🚀 强大功能

### 💥 影响范围

架构变更在审查时真正需要回答的问题是:会影响什么? 每个具有破坏性的迁移操作都会成为一个目标,并标注其风险、代码库中仍在读取它的位置,以及整个模型操作引发的级联影响。

migration-risk、impact 和 cascade 各自回答其中一部分;没人手动把它们串起来,因此由工具来完成。--format markdown 可生成便于发布的 PR 评论;--stats 会通过你自行运行的只读查询,将“可能已有数据”转化为 ~41 000 000 rows, 12.0 GB,CI 中无需接触任何数据库凭据。

🧭 架构漂移

无需启动 Django 即可运行 makemigrations --check。按顺序重放每个应用的迁移,得出迁移所隐含的字段集合,再与 models.py 中的声明进行比较。

Django 自带的检查需要可用的 settings 模块、可导入的应用注册表,以及所有依赖都已安装——在刚克隆的代码库或损坏的 venv 中无法满足,而这恰恰是最容易及时处理检查结果的时候。只有危险的情况会导致构建失败:声明了字段却从未迁移,意味着数据库中不会存在对应列,首次访问该列的查询就会报错。

🎯 内联诊断与 QuickFixes(18 条规则)

对 .py 文件进行静态分析,使用 Ruff 风格的代码(DOL001..DOL041)、Clippy 风格的 Applicability,并支持按规则覆盖严重性。.count() > 0 → .exists()、CharField 上的 null=True、缺少 on_delete、datetime.now() → timezone.now()、原始 SQL 中的 planner-GUC 覆盖项(enable_*、plan_cache_mode、jit*;仅提供诊断),以及另外十多项规则。

使用 # django-orm-lens-disable-next-line DOL007 进行内联抑制。

🧪 Factory 生成器

右键单击任意模型 → 生成 factory_boy DjangoModelFactory 框架代码,并根据字段类型选择 Faker 提供程序。CharField(max_length) 会按单词数范围调整,DecimalField(N,D) 会计算 left_digits=N-D,choices= 会映射为 Iterator,M2M 会生成 @post_generation。FK 链会递归提取相关 Factory。

也可通过每个模型类上方的 CodeLens 使用。

🕰 时间回溯架构差异

选择一个 models.py,再选择两个提交,即可获得可直接用于 PR 的 Markdown 格式类型化差异。事件包括 AddModel / DropModel / RenameModel / ModifyModel,并通过置信度评分进行重命名检测(Levenshtein + 字段形状 Jaccard)。

重命名会作为一等事件处理,绝不会拆成 Add + Drop。Blob-SHA LRU 缓存——未修改 models.py 的提交会共用其解析快照。

🔎 影响分析

“如果我删除这个字段,会有什么问题?”——右键单击字段或模型 → 扫描整个工作区,并按 Django 层分组显示结果(models、serializers、forms、admin、views、urls、templates、tests、migrations)。

结果带有 确定 / 可能 / 或许 置信度标签。支持 ORM 字符串引用(order_by("-author"))、关键字参数查找(filter(author__id=1))、Meta.fields 元组以及模板变量。

⚡ 交互式查询构建器

右键单击字段或模型 → 选择模板 → 将代码片段插入光标处(带制表位),或插入新的未命名缓冲区。

在 FK 上使用 .filter(field=?) 会自动追加 .select_related(...);.annotate(post_count=Count('post_set')) 会遵循 related_name;M2M 使用 .prefetch_related;还支持 .values('field').distinct() 和 .only('field')。

🎨 侧边栏体验全面升级

稳定的 TreeItem.id——刷新不再折叠树。丰富的 MarkdownString 工具提示,包含 command: 深层链接。活动栏徽标显示 DOL### 问题的数量。

FileDecorationProvider 徽标:FK 缺少 on_delete 时显示红色 !,字符串字段设置 null=True 时显示黄色 ~(徽标会像 Git 一样向上显示在父级 Model 行上)。


## 📸 效果展示
带有 Django ORM Lens 的 VS Code:模型树、views.py 中的 ORM 诊断信息和实时 ER 图

实时示例 — 真实的 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_diagramER 图 — 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 Codecode --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-commitrepo: https://github.com/FROWNINGdev/django-orm-lens + 两个钩子 ID✅
GitHub Actionsuses: FROWNINGdev/django-orm-lens@action-v1 — 注释或 SARIF✅
可通过 MCP Registry 发现官方 Model Context Protocol 服务目录✅
普通终端 / CIpip 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 Lensdjango-extensions graph_modelsdjango-schema-graphDjango AdminPyCharm 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.excludeGlobsstring[]见上文扫描时跳过的 Glob 模式
djangoOrmLens.autoRefreshbooleantrue在 models.py 发生变化时重新扫描
djangoOrmLens.codeFixes.enabledbooleantrueDOL### 诊断和 QuickFixes 的总开关
djangoOrmLens.rulesobject{}按规则设置严重级别:{ "DOL007": "off", "DOL013": "error" }
djangoOrmLens.rulesSelectstring[][]Ruff 风格的选择设置。["DOL0"] 仅运行查询集和模型规则
djangoOrmLens.rulesIgnorestring[][]Ruff 风格的忽略设置。["DOL03"] 禁用表单和视图规则

## 🔬 规则目录

18 项编辑器端检查(DOL001–DOL041),采用 Ruff 风格的代码、逐规则严重性等级和 Clippy 风格的适用性;此外还有 16 项 CLI 端迁移风险规则和静态 N+1 分析器。现在,每条规则都有自己的文档页面。

类别规则示例
查询集DOL001–DOL007.count() > 0 → .exists(),循环中的 FK 访问(N+1)
模型定义DOL011–DOL015ForeignKey 未设置 on_delete,字符串字段设置 null=True
日期时间DOL021–DOL022datetime.now() → timezone.now()
表单 / 视图DOL031–DOL032在 render() 中使用 locals(),Meta.fields = '__all__'
原始 SQLDOL041在应用代码中覆盖 SET enable_hashjoin = off、plan_cache_mode、jit
迁移风险16 条规则添加 NOT NULL 字段但未设置默认值、会锁表的索引构建、不可逆的数据迁移
静态 N+11 个分析器循环中访问 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 工具窗口已经很好用了,因此新增价值有限。如果有足够多的人提出需求,再开发才值得。

🆘 支持


📜 许可证

MIT © FROWNINGdev


为关心代码库的开发者打造。

市场 · PyPI · GitHub · 问题 · 讨论 · 赞助

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。