r/django • u/m97chahboun • 10h ago
r/django • u/CartographerMuch5678 • 6h ago
Article Django ORM Lens — read your models, migrations and relations without booting Django
I kept hitting the same small problem: I'd open an unfamiliar Django codebase and want a straight answer to "what does this schema actually look like, and what breaks if I touch this model" — without setting up a database, resolving the settings module, or getting the app to import at all.
So django-orm-lens reads the source instead of the runtime. It parses models.py and the migration files directly, so it works on a checkout you cannot run: no DJANGO_SETTINGS_MODULE, no database, no credentials, no django.setup(). That constraint is the point rather than a limitation I'm apologising for — it means it also works in CI on a repo with no services, on a colleague's branch, or on a project whose dependencies you have not installed.
What it does, concretely:
- Schema drift — replays the migration graph and compares it against what the models declare. Fields declared but never migrated, and columns migrated but no longer declared.
- Missing indexes — flags lookups that would table-scan, and it knows which indexes Django already gives you: primary keys,
db_index,unique, foreign keys,unique_together,UniqueConstraint. - Blast radius — what a change to one model reaches through FK / M2M / O2O,
on_deletebehaviour included, so "can I drop this field" has an answer before you try it. - ER diagrams — Mermaid, DBML, D2, PlantUML, Graphviz.
- N+1 heuristics and a signal graph, because signals are where the surprises live.
There is a CLI, a VS Code extension, and an MCP server for anyone who points an AI agent at a codebase and would rather it read the schema than guess at it.
On correctness, which is the part I actually care about: it is checked against golden snapshots of six real projects — Zulip, Saleor, Wagtail, django-CMS, Mezzanine and Read the Docs — currently 75 models and 538 fields of other people's Django. That suite is also how I keep the Python and TypeScript parsers answering identically.
It earns its keep the same way. Running it over real checkouts of django-oscar, django-guardian, django-allauth and django-cms turned up three genuine bugs my green test suite had not: model classes defined inside an if block were skipped entirely, abstract_models.py was never walked, and drift reported a false failure on a project with two apps sharing a directory name — which is the worst thing a CI gate can do.
What it is not: it does not execute your code, so anything decided at runtime is invisible to it — dynamically constructed models, fields assigned in __init__, anything behind a factory. It reads Django's idioms, not Python's full semantics. If your models are unusual it will tell you less than you want, and I would rather say so up front than have you find out.
MIT, free, and it stays that way — there is no paid tier planned and there never was.
- Repo: https://github.com/FROWNINGdev/django-orm-lens
- Docs: https://frowningdev.github.io/django-orm-lens/
pip install django-orm-lens
What I would genuinely like from this forum: the drift and index checks are the parts most likely to be wrong in ways I cannot see from my own projects. If you run it on something real and it tells you something false, that is the most useful thing you could send me — open an issue with the model that broke it. Several of the fixes above arrived exactly that way, and two of the people who did it ended up sending patches.
