Django Orm Lens について
Django ORM Lens は静的解析によって Django モデルの ER 図、N+1 検出、マイグレーションリスクの確認を行います。Django の起動もデータベースも不要です。VS Code 拡張機能、CLI、MCP サーバーとして提供され、エディタ利用者、CI、AI エージェントの利用者を想定しています。
主な機能
- 01データベース不要の静的解析
- 02VS Code サイドバーのツリーと ER 図
- 03N+1 クエリとマイグレーションリスクの検出
- 04クイックフィックス付きの 18 のルール
- 05SARIF 出力と GitHub Action に対応した CLI
活用シーン
- 01不慣れな Django プロジェクトでのモデル関係の把握
- 02CI での N+1 クエリや危険なマイグレーションの検出
- 03AI エージェントによる MCP 経由のスキーマ照会
MCP 対応
オプションの MCP サーバーとして 13 個の読み取り専用ツールを提供し、AI エージェントが Django のスキーマについて回答できるようにします。Django の読み込みやアプリの起動は不要です。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
English · Русский · Español · 中文
Django ORM Lens
Django を起動せずに、ER 図、N+1 検出、マイグレーションリスクのチェックを実現します。
モデルグラフ全体を、エディターのサイドバーでリアルタイムに表示し、CI のゲートとして活用し、MCP 経由で AI エージェントからの質問に回答できます。すべて静的解析で実現します。データベースも、runserver も、動作する venv も必要ありません。
置き換えるもの: 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
クローンしたばかりで、venv が壊れていて、設定モジュールがなくても、プロジェクト内のすべてのアプリとモデル、さらに N+1 ループやリスクの高いマイグレーションを、ターミナルですぐに確認できます。(uvx は uv に含まれています。pipx run でも同じように使えます。)
続いて利用方法を選びます — 3 種類の配布形態で、パーサーコアは共通です。
| 利用者 | インストール | 利用できる機能 |
|---|---|---|
| エディターユーザー — VS Code / Cursor / Windsurf / VSCodium | code --install-extension frowningdev.django-orm-lens | .filter() のフィールド補完、サイドバーツリー、ライブ ER 図、ホバーカード、QuickFix 付きの18個の lint ルール |
| ターミナル/CI ユーザー | pip install django-orm-lens | 17個のサブコマンド、SARIF + PR アノテーション、pre-commit フック、GitHub Action |
| AI エージェントユーザー — Cursor / Claude Code / Aider / Zed / Continue | pip install "django-orm-lens[mcp]" | 正確な情報に基づいてスキーマに関する質問に回答する、読み取り専用の13個の MCP ツール |
MCP の設定は JSON ブロック1つで完了します。インテグレーションをご覧ください。DJANGO_ORM_LENS_ROOT に Django プロジェクトの絶対パスを指定します。
🆓 有料プランで提供される機能を、無料かつMITライセンスで
スキーマレビューは、ほとんどの場所で有料カテゴリに分類されています。すべてのプルリクエストをレビューするボット、作成元の関数を超えてクエリセットを追跡する分析、スキーマのドリフトを検出するチェック、実際のテーブル統計に基づくインデックスの提案——通常、こうした機能はシート単位またはデータベース単位のサブスクリプションが必要です。
これらはすべて、MITライセンスで、プランによる制限も、シート数の制限も、アカウントも、テレメトリもなく利用できます。
| 通常は有料プランとして販売される機能 | こちら |
|---|---|
| スキーマ変更用のPRレビューボット——一度投稿し、その後は既存の投稿を更新します | blast-radius + Action |
| 関数をまたいでクエリセットを追跡する分析 | nplusone |
| スキーマのドリフト検出 | drift |
| 観測されたQuerySetの使用状況に基づくインデックスの提案 | suggest-indexes |
| 実際のテーブルサイズを考慮したマイグレーションリスクの評価 | blast-radius --stats |
| 破壊的なマイグレーションの影響範囲 | blast-radius |
| フィールド削除が複数レイヤーに与える影響 | impact |
Proプランはなく、今後も予定していません。 このツールで午後の作業が節約できたなら、お願いしたいのはスターだけです。
📊 利用状況
次に見慣れない Django プロジェクトを触るとき、このツールのおかげで
grepを使わずに済んだら、スターを付けて、ほかの人にも見つけてもらいましょう。
📈 スター数の推移
⚡ インストール
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 コーディングエージェント:
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件スクロールし、ファイルを5つ開き、Ctrl+F で class Order を検索して、ForeignKey('otherapp.Something') という文字列が400行続くのを読み、2つ前のファイルで分かったことを思い出そうとします。
毎回、半日が消えます。どのプロジェクトでも。
✨ Django ORM Lens を使うと
📚 すべてを一覧できるツリーすべてのアプリ → すべてのモデル → すべてのフィールド → すべての アイコンを見れば、 |
🕸️ リアルタイム ER 図コマンドを1つ実行するだけで、スキーマ全体の Mermaid エンティティ・リレーションシップ図が開きます。編集に合わせて再描画される様子を確認できます。SVG にエクスポートできます。
|
🔎 リレーションをホバーで確認任意の Python ファイル内で |
🧭 定義へ移動ツリー内のフィールドをクリックすると、カーソルが該当行に移動します。アプリ名やモデル名でツリーを絞り込めます。分割された |
⚡ 設定不要
|
🎨 VS Code ネイティブの UIダークテーマ。ライトテーマ。お好みのテーマ。アイコンテーマ、フォント、キー割り当てに合わせて表示されます。派手な装飾も、独自のブランド表現もありません。 |
🚀 高度な機能
|
### 💥 影響範囲
スキーマ変更のレビュー時に実際に問われるのは、どこに影響するのか? ということです。破壊的なマイグレーション操作はすべて、リスクを伴う対象になります。さらに、コードベース内でまだその対象を読み取っている箇所や、モデル全体に対する操作の場合は、連鎖的な影響も把握できます。
|
🧭 スキーマのドリフトDjango を起動せずに Django 標準のチェックには、動作する設定モジュール、インポート可能なアプリレジストリ、すべての依存関係のインストールが必要です。新規クローンや壊れた venv ではこれらが使えないことがありますが、そうした状況こそ、答えが分かれば最も早く対処できます。ビルドを失敗させるのは危険な方向の不整合だけです。つまり、フィールドが宣言されているのにマイグレーションされていない場合、カラムは存在せず、そのフィールドに初めてアクセスするクエリがエラーになります。 |
🎯 インライン診断と QuickFix(18 ルール)Ruff 形式のコード(
|
🧪 ファクトリージェネレーター任意のモデルを右クリックすると、フィールド型に応じた Faker プロバイダーを使う 各モデルクラスの上に表示される CodeLens からも利用できます。 |
🕰 タイムトラベルスキーマ差分
名前変更は独立したイベントとして扱われ、 |
🔎 影響分析「このフィールドを削除すると何が壊れるか?」任意のフィールドまたはモデルを右クリックすると、ワークスペース全体をスキャンし、Django のレイヤー(モデル、シリアライザー、フォーム、管理画面、ビュー、URL、テンプレート、テスト、マイグレーション)ごとに結果を分類します。 検出結果には、信頼度を示す 確実 / 可能性が高い / 可能性がある のタグが付きます。ORM の文字列参照( |
⚡ インタラクティブクエリビルダー任意のフィールドまたはモデルを右クリックし、テンプレートを選択すると、タブストップ付きのスニペットがカーソル位置、または新しい未保存バッファーに挿入されます。 外部キーに対する |
🎨 サイドバー UX の全面刷新安定した
|
## 📸 表示例
ライブサンプル — 実際の 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 コーディングエージェント向け
VS Code 拡張機能を支えるパーサーは、スタンドアロンの Python パッケージとしても提供されています。オプションの MCP(Model Context Protocol)サーバーを使えば、MCP 対応の AI エージェントは 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 サーバー
エージェントに一度登録するだけで、読み取り専用の 13 個のツールを利用できます:
| ツール | 用途 |
|---|---|
list_apps | ワークスペース内のすべての Django アプリとモデル数 |
list_models | app.Model の一覧。アプリによる絞り込みも可能 |
describe_model | 1 つのモデルのフィールド、リレーション、Meta の詳細 |
find_relations | 1 つのモデルの参照元および参照先のリレーション |
cascade_preview | 1 つの delete() の影響範囲を on_delete ごとに分類して表示 |
er_diagram | ER 図 — mermaid / dbml / d2 / plantuml / dot |
describe_migration_dependency | アプリごとのマイグレーション DAG:ルート、リーフ、アプリ間の依存関係 |
suggest_indexes | 実際の QuerySet の使用状況に基づく Meta.indexes の提案 |
signal_graph | @receiver デコレーターから生成した Sender→signal→handler グラフ |
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": "…"})を返すため、
エージェントは自力で修正できます。DJANGO_ORM_LENS_ALLOWED_ROOTS を使って
サンドボックスを任意で設定できます(Windows では ;、それ以外では : で区切ります)。
エージェントスキル
ツールは何が事実かをエージェントに伝え、スキルはその情報をどう活用するかを
伝えます。skills/django-orm-lens は SKILL.md
パッケージで、マイグレーションレビュー、安全な名前変更と削除、
N+1 の修正とカスケードの確認のためのプレイブック、16 個すべてのマイグレーション
ルールに対する安全な書き換え例、そして 1 つのコマンドで判定
(BLOCK / FIX BEFORE DEPLOY / SHIP)を行う audit.py が含まれています。MCP サーバーに
接続している場合はそれを使い、接続していない場合は uvx 経由で CLI にフォールバックします。
- Agensi からインストールできます(無料)。または
- 次の例のように、フォルダーをエージェントのスキルディレクトリにコピーできます(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 ボット — スキーマ全体のレビューを 1 つのコメントにまとめ、プッシュのたびに新しいコメントを追加するのではなく、既存のコメントを更新します。
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 は git diff ではなく、API から PR のファイル一覧を取得します。これは、actions/checkout のデフォルトが fetch-depth: 1 で、ベースコミットがローカルの履歴に含まれていないためです。push イベントでは、どちらのフラグも失敗させずに通知を出してスキップするため、1 つのワークフローで両方のトリガーに対応できます。
この Action は PyPI からインストールするため、
blast-radiusとdriftには py-1.7.0 以降が必要です。ワークフローでバージョンが変わらないようにするには、version: 1.7.0で固定してください。未リリースのビルドを実行する場合は、install: falseを追加してソースを自分でインストールしてください。このリポジトリ独自のワークフローではその方法を使っており、すべての PR で Action を検証しています。
pre-commit — ローカルでインストール不要の 2 つのフックです。
# .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 | mcp.json に django-orm-lens-mcp を追加 | ✅(MCP 経由) |
| Continue.dev | MCP サーバーを ~/.continue/config.json に登録 | ✅(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 + 2 つのフック 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 の同梱モデルグラフを解析します。実際の models.py 13,478 行にわたる 59 個のモデルを、ノート PC でエンドツーエンド約 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の中で迷っている方。 - 契約エンジニア/フリーランスエンジニア:初めての週ではなく、最初の 1 時間で不慣れな Django プロジェクトを把握する必要がある方。
- 新入社員を受け入れるチーム:ドキュメント基盤を用意せずに、スキーマの概要をひと目で確認したいチーム。
- AI エージェントを活用するユーザー(Cursor / Aider / Zed / Continue / 任意の MCP 対応クライアント):データベースの認証情報を渡したり Django を起動したりせずに、エージェントにスキーマの質問へ正確に回答させたい方。
- CI パイプライン:プロジェクトをインポートせずに、スキーマの形状(たとえば「誤って
related_nameを壊していないか?」)を検証したい場合。 - 個人のインディー開発者:壊れた venv や他人のノート PC を使っている場合でも、
runserverもmanage.py migrateも不要で、そのまま動作します。
## 🗺️ 市場での位置付け
Django ORM Lens は、エディターツールとAI エージェントツールの交差点に位置しています。この領域をカバーする既存のパッケージはありません。
| セグメント | 既存の選択肢 | 必要となるもの |
|---|---|---|
| 起動してグラフ化 | django-extensions graph_models | Graphviz、Django の設定、動作する DB URL が必要です |
| Web ベースのビューアー | django-schema-graph | Django サーバーの起動が必要で、さらに障害の原因となるものが増えます |
| 管理パネル | Django Admin | runserver、認証、データベースが必要です。データには最適ですが、アーキテクチャには向いていません |
| エディタープラグイン | PyCharm の Django Structure | PyCharm に限定され、CLI も AI エージェント向け機能もありません |
| MCP サーバー | (これまで存在しませんでした) | AI エージェントはソースからスキーマを推測するため、完全ではありません |
Django ORM Lens は、1 つのパーサーから 3 つの形態を提供する唯一のツールです。 VS Code 拡張機能(あらゆる Code フォークに対応)、依存関係ゼロの CLI(ターミナルと CI 向け)、MCP サーバー(AI エージェント向け)を提供します。すべて静的に動作し、すべて無料で、すべて 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 エージェント向け 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 エージェントがあらゆるチェックアウトで使える唯一のツールです。
⚙️ 設定
デフォルト設定は、適切で使いやすい値になっています。調整が必要な場合は、次のとおりです。
// .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"] を指定すると、フォームとビューのルールを無効にします |
## 🔬 ルール一覧
Ruff 形式のコード、ルールごとの重要度、Clippy 形式の適用可能性を備えたエディター側のチェックが18個(DOL001~DOL041)あります。さらに、CLI 側のマイグレーションリスクルールが16個、静的 N+1 アナライザーが用意されています。すべてのルールに個別のドキュメントページが用意されています。
| カテゴリ | ルール | 例 |
|---|---|---|
| Queryset | DOL001~DOL007 | .count() > 0 → .exists()、ループ内での FK アクセス(N+1) |
| モデル定義 | DOL011~DOL015 | on_delete を指定しない ForeignKey、文字列フィールドでの null=True |
| 日時 | DOL021~DOL022 | datetime.now() → timezone.now() |
| フォーム/ビュー | DOL031~DOL032 | render() での locals()、Meta.fields = '__all__' |
| Raw SQL | DOL041 | アプリケーションコード内での SET enable_hashjoin = off、plan_cache_mode、jit の上書き |
| マイグレーションリスク | 16個のルール | デフォルト値を指定しない NOT NULL 列の追加、テーブルをロックするインデックス構築、元に戻せないデータマイグレーション |
| 静的 N+1 | 1つのアナライザー | select_related/prefetch_related を使わないループ内での FK/M2M アクセス |
→ ルールの完全なリファレンス — 不適切な例と適切な例、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 形式)、検出ロジックに手を加えることなく、1つのルールに複数の修正機能を追加できます。
🧭 コマンド
コマンドパレット(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 | モデルを右クリックすると、そのモデルを参照するすべての FK を QuickPick で表示します |
Django ORM Lens: Generate factory_boy Factory | モデルを右クリックするか CodeLens を使うと、DjangoModelFactory のひな形を生成します |
Django ORM Lens: Schema Diff (Time-Travel) | 2つのコミットを選択すると、型付きの差分を 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 エージェント向けの Python CLI と MCP サーバー
- 空のワークスペース向けウェルカムビュー
- パスの安全性を確保した定義へのジャンプと、サニタイズされたホバーマークダウン
- 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 Registry と Glama.ai に掲載
- v0.6.0 — CLI
nplusone— 静的 N+1 検出器(ループ内でのselect_related/prefetch_relatedを伴わない FK/M2M アクセスを検出) - v0.6.0 — CLI
migration-risk—migrations/*.py内のリスクの高い操作にフラグを付ける(現在は15ルール) - v0.6.0 — CLI
diff— PR レビュー向けに、2つのスキーマ JSON ダンプを比較 - 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(...))を解析可能に。Django Ninja 1.6 の再現コード で報告された @jsabater(#25) - v0.7.4 — PEP-695 ジェネリッククラスヘッダー(Python 3.12 以降):
class Container[T](models.Model):を解析可能に - v0.7.5 — エイリアス付き models モジュール(
from django.db import models as m)とサードパーティのフィールドパッケージ(jsonfield.JSONField)を検出可能に - v0.7.6 — タブインデントされたモデル本体を解析可能に(タブをデフォルトとするエディターでモデルが空に表示される問題を解消)
- v0.8.0 — インライン QuickFixes:16ルール(
DOL001..DOL032)、ルールごとの重大度、Ruff スタイルの選択/無視、インラインの# django-orm-lens-disable-next-line - v0.8.0 — ファクトリー生成:任意のモデルから
factory_boyのひな形を生成し、フィールド型に応じた Faker プロバイダーを設定 - v0.8.0 — タイムトラベルスキーマ差分:2つのコミットを選択し、名前変更を第一級で検出する型付きマークダウン差分を生成
- v0.8.0 — 影響分析:ワークスペース全体のすべての Django レイヤーを対象にフィールド参照をスキャンし、確実性を「確実」「可能性が高い」「可能性がある」のタグで表示
- v0.8.0 — インタラクティブクエリビルダー:右クリック → テンプレート → カーソル位置にスニペットを挿入。文法を認識し、FK には
.select_relatedを付与し、related_nameを尊重 - v0.8.0 — サイドバー UX の全面刷新:安定した
TreeItem.id、command:ディープリンク付きMarkdownStringツールチップ、FileDecorationProviderバッジ、アクティビティバーのTreeView.badge、when 条件で切り替わる3つのviewsWelcome状態
v1.5.0 — 「1つのコア、3つのインターフェース」ウェーブ
- CI 形式:SARIF 2.1.0 +
--format githubによるnplusoneおよびmigration-riskの PR アノテーション - 4 つのアナライザーを MCP 専用から CLI に昇格:
suggest-indexes、signals、migration-deps、cascade -
er --format dbml | d2 | plantuml | dot— コミュニティ標準のダイアグラム出力(dbdiagram.io、D2、PlantUML、Graphviz —dotは @JJordan0C によるコントリビューション) - 3 つの新しい 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 による、本番環境の行数の任意取得(ツールが DB 認証情報を保持することはありません) -
nplusoneが関数をまたいで解決 — ヘルパーから返された queryset を、それを使用するループまで追跡 -
blast_radius、drift、impactを MCP ツールとして公開 — AI エージェント向けの 13 個のツール -
driftがレポートと--helpで!!/~のマークを説明するようになりました — @sevdog から報告(#57) -
driftが抽象基底クラスからの継承を追跡 — Django の扱いと同様に、抽象基底クラスのフィールドを具象子クラス自身のフィールドとして数えます — @sevdog から報告(#58) -
suggest-indexが Django によってすでに作成されたインデックスを認識 — 主キー(pkとidは同じ検索)、db_index、unique、外部キー、unique_together、UniqueConstraint— @sevdog から報告(#60)。同じ原因を @RinZ27 が独立して発見(#61) - 6 つ目のゴールデンフィクスチャ — 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。4.0 以降のstartprojectテンプレートでのUSE_TZ = Trueは別の設定として明記し、timezone.now()が常に UTC の aware な日時を返すという記述も削除 — ページの翻訳中に @Justine0211 が発見(#52) -
parity_input.pyフィクスチャに、実際のmodels.pyにあるmodelsのインポートを追加 — @RinZ27 によるコントリビューション(#64)
py-1.9 → 1.12 — 実際のチェックアウト環境への対応強化 django-oscar、django-guardian、django-allauth、django-cms の実際のチェックアウトに対して CLI を実行して判明しました。フィクスチャでは検出できませんでした。これらはいずれもテストスイートがすべて成功していても見落とされており、そのうち 2 つでは、ツールが誤った内容を自信ありげに回答していました。
- モジュールレベルのブロック内で宣言されたモデルを解析 — スワップ可能モデルのイディオム(
if not is_model_registered(...):に続くインデントされたclass)は、プラグイン可能な Django フレームワークならどれも使用しています。^classを基準にクラスを検出する方式では、このイディオムを見落としていました。django-oscar では、検出されるモデル数が 12(すべて独自のtests/ディレクトリ内のもの)から 82 に増えました。6 つすべてのゴールデンスナップショットはバイト単位で同一のままです。0 列目から始まるクラスは、以前とまったく同じように解析されます -
abstract_models.pyをmodels.pyと併せて読み込み — プラグイン可能なフレームワークでは、抽象基底クラスをこちらに置き、models.pyには具象サブクラスだけを記述します。そのため、django-oscar の 83 モデルのうち 72 モデルでは、モデル間のフィールド数が 0 と報告されていました。現在は 8 モデルになり、いずれも正しい結果です。これらは具象モデルをサブクラス化しており、マルチテーブル継承では列が親のテーブルに残ります - アプリディレクトリ名が重複していても、
driftがビルドを失敗させなくなりました — リプレイされたマイグレーションの状態をアプリ名ごとに統合し、すでに同じキーを使っている宣言側に合わせています。実際の django-guardian のチェックアウトでは、ブロッキング件数が 1 → 0 になり、矛盾する重複行も消えます。一方で、マイグレーションされていないフィールドが実際にあれば、引き続きブロックします - django-mptt のモデルを正しく検出 —
MPTTModelを認識済みの基底クラスとして扱い、TreeForeignKey/TreeOneToOneField/TreeManyToManyFieldは継承元の Django フィールドとして報告するため、TreeForeignKey('self', ...)は通常のForeignKey('self', ...)と同じように、正確に自己エッジを描画します。django-mptt依存関係は追加しません。パーサーは破損した venv に対しても引き続き動作します。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 メッセージを送信元ではなくオリジンで検証するようになり、競合するリーフマイグレーションも検出します。これは、同じ親を持つと主張する2つのマイグレーションのことで、Django はmigrateの実行時に初めて警告していました - v0.10.1 — Marketplace の掲載情報で、影響分析、影響範囲、スキーマドリフトを紹介し、ツールが無料かつ MIT ライセンスで、Pro プランがないことを明記しました。ストアのページには、2世代前の内容であるサイドバーと ER 図がまだ記載されていたため、それらの機能を探している人に見つけてもらえませんでした。メタデータが反映されるのは公開後のみのため、これだけのためのリリースが必要でした
- v0.11.0 — django-mptt 対応の TypeScript 側を、後のリリースに含めず独立したリリースとして公開しました。py-1.12.0 の公開からこのビルドまでの間、CLI と拡張機能の間で django-mptt スキーマの内容に食い違いがありました。共有のゴールデンフィクスチャは、まさにこの問題を防ぐために用意されています
- v0.12.0 — ER 図を開く操作がユーザー自身によって3回行われると、拡張機能が GitHub のスターを依頼します。インストール時ではありません。ツールが何もしていないうちにプロンプトが表示されると、反射的に閉じられ、その後もずっとユーザーに無視されてしまうからです。すでに開いているパネルを再描画するサイドバーの更新はカウントしません。ユーザーが何かを求めた操作ではないためです。「後で」と「今後表示しない」は別々の状態として保存されるため、延期すると12回開いた後に一度だけ再度依頼します。プロンプトの表示は生涯で最大2回です。このポリシーは純粋関数であり、VS Code ホストがなくても実行できる6つのテストでカバーされています
- 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 に移植 — 1つのルールカタログ、3つのインターフェース
今後
- サードパーティ製フィールドへの対応 —
django-model-utils(django-taggitは py-1.11.0、django-mpttは py-1.12.0/v0.11.0 で対応済み) - JetBrains/PyCharm プラグイン(需要があれば)
該当するissueに 👍 を付けて投票してください。
## ❓ よくある質問
コードがサーバーに送信されることはありますか?
いいえ。すべてのデータはお使いのマシン内にとどまります。パーサーは純粋な TypeScript(拡張機能)または純粋な Python(CLI)で実装されています。LLM の呼び出し、テレメトリー、分析、エラー報告は一切ありません。Mermaid レンダラーは VS Code の Webview サンドボックス内で実行されます。
Poetry/uv/conda/仮想環境なしでも動作しますか?
はい。拡張機能は Python ソースを直接読み取るため、Django をインポートせず、どのパッケージマネージャーを使っているかも問いません。CLI には Python 3.9 以降が必要ですが、それだけです。
models/ パッケージ内の複数ファイルにモデルを分けています。対応していますか?
はい。v0.2.0 以降に対応しています。拡張機能と CLI の両方が、従来の
models.py とあわせて models/*.py を検索します。
DRF シリアライザー、Wagtail、Oscar、サードパーティ製のベースモデルと一緒に使えますか?
Django モデルのように見えるクラスであれば検出されます。
models.Model のサブクラス、Abstract で始まる抽象ベースクラス、Mixin で終わる一般的なミックスイン、TimeStampedModel や PolymorphicModel のような既知のベース名が対象です。モデルではないクラス(ModelAdmin、ModelSerializer、Form、View、Manager など)は除外されます。
どの AI エージェントが MCP サーバーを利用できますか?
Cursor、Aider、Continue.dev、Zed など、プロトコルに対応したあらゆる MCP 互換クライアントで利用できます。
command にインストール済みの django-orm-lens-mcp バイナリを指定するだけです。インテグレーションのセクションをご覧ください。
CI でスキーマのリグレッションを防ぐにはどうすればよいですか?
設定不要の方法が 3 つあります。2 つの pre-commit フック、複合 GitHub Action(PR に注釈を付ける場合は
format: github を指定して uses: FROWNINGdev/django-orm-lens@action-v1 を使用)、または --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 サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。