Skip to main content

django-orm-lens

PyPI Python Downloads License

Static analysis + MCP server for Django models. Terminal- and AI-agent-friendly.

Listed in the official MCP Registry as io.github.FROWNINGdev/django-orm-lens.

Ships with a zero-dependency parser, a JSON/Markdown/table CLI, and an optional MCP (Model Context Protocol) server so any AI coding agent — Cursor, Aider, Continue, and any other MCP client — can navigate your Django schema without importing Django or spinning up your app.

Companion to the Django ORM Lens VS Code extension.

Paid-tier capabilities, free and MIT

Schema review is a paid category nearly everywhere. A bot that reviews every pull request, analysis that follows a queryset past the function it was built in, a check that catches schema drift, index advice grounded in real table statistics — those normally sit behind a per-seat or per-database subscription.

All of it is here, MIT-licensed, with no tier gate, no seat count, no account and no telemetry:

Capability usually sold as a paid tier Here
PR review bot for schema changes — posts once, then updates in place blast-radius + the GitHub Action
Analysis that follows a queryset across functions nplusone
Schema drift detection drift
Index proposals from observed QuerySet usage suggest-indexes
Migration risk weighed against real table sizes blast-radius --stats
Blast radius of a destructive migration blast-radius
Cross-layer impact of removing a field impact

There is no Pro tier, and none is planned.


Install

# Core CLI (zero third-party deps)
pip install django-orm-lens

# With the MCP server (adds the `mcp` package)
pip install "django-orm-lens[mcp]"

Requires Python 3.9+. Works on Linux, macOS, and Windows.


CLI usage

# Scan a Django project for models (JSON, Markdown, or table)
django-orm-lens scan -f json
django-orm-lens scan -f markdown
django-orm-lens scan -f table

# Describe one model
django-orm-lens describe blog.Post
django-orm-lens describe Post -f json

# Compact hover card (great for pipeing into your editor)
django-orm-lens hover blog.Post

# Flat list — pipes into fzf, grep, etc.
django-orm-lens list | fzf

# ER diagram — Mermaid (default), DBML, D2, or PlantUML
django-orm-lens er > schema.mmd
django-orm-lens er -f dbml > schema.dbml     # paste into dbdiagram.io
django-orm-lens er -f d2 > schema.d2         # render: d2 schema.d2 schema.svg
django-orm-lens er -f plantuml > schema.puml

# Diff two schema dumps (exit 1 on changes — CI-friendly)
django-orm-lens diff before.json after.json

# Static analyzers — text, json, sarif, or github annotation output
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          # delete blast radius by on_delete

Every command accepts --path <dir> and repeatable --exclude <glob>. Defaults skip migrations/, venv/, .venv/, env/, and node_modules/.


MCP server — for AI coding agents

The MCP server exposes ten read-only tools that any MCP-compatible agent can call while it edits your Django project:

Tool Purpose
list_apps Every Django app in the workspace with model counts
list_models Flat app.Model list, optional app filter
describe_model Full field / relation / Meta detail for one model
find_relations Inbound + outbound relations for one model
cascade_preview Blast radius of one delete(), grouped by on_delete
er_diagram ER diagram — mermaid / dbml / d2 / plantuml
describe_migration_dependency Per-app migration DAG: roots, leaves, cross-app deps
suggest_indexes Meta.indexes proposals from observed QuerySet usage
signal_graph Sender→signal→handler graph from @receiver decorators
nplusone_scan Static N+1 findings for the whole workspace

Start the server manually

django-orm-lens-mcp     # dedicated entry point
# or
django-orm-lens mcp     # subcommand

Workspace resolution (py-1.3.0+). Priority: explicit workspace_root argument on the tool call → DJANGO_ORM_LENS_ROOT env var → current working directory. If none resolves to a Django project (manage.py, django in pyproject.toml, or any models.py) you get a structured error envelope back — {"error": "WORKSPACE_NOT_DJANGO", "hint": "…"} — instead of an empty list, so the agent knows what to do next.

Optional sandbox: set DJANGO_ORM_LENS_ALLOWED_ROOTS (;-separated on Windows, :-separated elsewhere) to a whitelist of prefixes; any path outside them is rejected with WORKSPACE_NOT_ALLOWED.

Register it with an agent

Cursor — add to ~/.cursor/mcp.json:

{
  "mcpServers": {
    "django-orm-lens": {
      "command": "django-orm-lens-mcp",
      "env": { "DJANGO_ORM_LENS_ROOT": "/abs/path/to/your/project" }
    }
  }
}

Any MCP client — same shape, generic tool. Point command at the installed django-orm-lens-mcp binary. Two ways to tell it which Django project to scan:

  1. Set DJANGO_ORM_LENS_ROOT in env — the whole session uses one project. Simplest for single-repo workflows.
  2. Pass workspace_root on each tool call — the agent switches projects per call. Useful for mono-repos and multi-workspace setups.

The tool signatures include workspace_root: str = "" as an optional parameter, so any agent inspecting tools/list sees it and can supply it.


CI gates

diff and nplusone exit 1 on findings; migration-risk exits 1 on critical findings (--exit-zero for report-only). Two annotation-ready formats: --format github prints ::warning/::error workflow commands (PR annotations with no extra permissions), --format sarif emits SARIF 2.1.0 for github/codeql-action/upload-sarif.

pre-commit users get two ready-made hooks:

repos:
  - repo: https://github.com/FROWNINGdev/django-orm-lens
    rev: py-v1.8.1
    hooks:
      - id: django-orm-lens-nplusone
      - id: django-orm-lens-migration-risk

GitHub Actions users get a composite action: uses: FROWNINGdev/django-orm-lens@action-v1 with command: / format: inputs.


Why?

Django's ORM is Python, and Python is dynamic. AI agents that only see models.py as raw text miss:

  • which fields belong to which model;
  • the direction and cardinality of every relation;
  • what Meta.ordering, unique_together, and constraints actually contain;
  • which app owns which model when the project uses split models/ packages.

django-orm-lens gives them a static, deterministic, JSON view of the schema — no Django boot, no database, no side effects. And you get a nice CLI for humans too.


Programmatic API

from django_orm_lens import scan_workspace

index = scan_workspace(".")
for app in index.apps:
    for model in app.models:
        print(f"{app.name}.{model.name}{len(model.fields)} fields")

# The full parsed tree serialises to the same JSON schema the VS Code
# extension emits, so tools can share it interchangeably.
import json
json.dumps(index.to_dict(), indent=2)

Links

MIT licensed.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_orm_lens-1.13.0.tar.gz (167.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_orm_lens-1.13.0-py3-none-any.whl (106.1 kB view details)

Uploaded Python 3

File details

Details for the file django_orm_lens-1.13.0.tar.gz.

File metadata

  • Download URL: django_orm_lens-1.13.0.tar.gz
  • Upload date:
  • Size: 167.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for django_orm_lens-1.13.0.tar.gz
Algorithm Hash digest
SHA256 faa18218523b07f55947d339a3162eb7d9362f74fc2f6b926a56eb1e28394fa0
MD5 7f4cf6287f104bfcafcc5457e4f2aa7d
BLAKE2b-256 f9f9fd686be5e37498f5772103eb4352c7f8f0a7b31e3617bb800b9fb7f17200

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_orm_lens-1.13.0.tar.gz:

Publisher: publish-pypi.yml on FROWNINGdev/django-orm-lens

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_orm_lens-1.13.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_orm_lens-1.13.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0a503ad61bcb49b5b2cf660dd23e5447a3a7464370666adf6b822147e7a4f584
MD5 3ef381097bf271a6aff7aa048ecc7ede
BLAKE2b-256 cb9b4f960b857caee117eeb72977282d9e528f5dcf37266fc843a207550cf6ec

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_orm_lens-1.13.0-py3-none-any.whl:

Publisher: publish-pypi.yml on FROWNINGdev/django-orm-lens

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

1.13.0 This release

2 files

1.12.0

2 files

1.11.0

2 files

1.10.0

2 files

1.9.0

2 files

1.8.1

2 files

1.8.0

2 files

1.7.1

2 files

1.7.0

2 files

1.6.0

2 files

1.5.1

2 files

1.5.0

2 files

1.4.0

2 files

1.3.0

2 files

1.2.7

2 files

1.2.6

2 files

1.2.5

2 files

1.2.4

2 files

1.2.3

2 files

1.2.2

2 files

1.2.1

2 files

1.2.0

2 files

1.1.0

2 files

1.0.17

2 files

1.0.16

2 files

1.0.15

2 files

1.0.14

2 files

1.0.13

2 files

1.0.12

2 files

1.0.11

2 files

1.0.10

2 files

1.0.9

2 files

1.0.8

2 files

1.0.7

2 files

1.0.6

2 files

1.0.5

2 files

1.0.4

2 files

1.0.3

2 files

1.0.2

2 files

1.0.1

2 files

1.0.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page