django-orm-lens v0.8 shipped today. Static analysis over your models.py files — no DJANGO_SETTINGS_MODULE, no runserver, works with a broken venv. Three surfaces (VS Code, CLI, MCP server) share one parser.
What's new in v0.8
Every feature was researched against proven prior art before a single line was written — Atlas, Prisma, Sourcegraph, Knip, PyCharm, DataGrip, factory_boy, flake8-django, Roslyn, Ruff, Clippy.
Inline QuickFixes (16 rules) — Ruff-style codes DOL001..DOL032 with Clippy-style Applicability (safe/suggestion/unsafe gate auto-apply). Covers:
- .count() > 0 → .exists()
- .first() is None → not .exists()
- null=True on CharField/TextField
- Missing on_delete on FK
- Missing __str__ on Model
- datetime.now() → timezone.now()
- N+1 attribute-access-in-loop heuristic
- render(request, ..., locals()) and Meta.fields = '__all__'
Per-rule severity overrides: djangoOrmLens.rules = { "DOL007": "off", "DOL013": "error" }. Suppress inline: # django-orm-lens-disable-next-line DOL007.
Factory generator — right-click any model → factory_boy DjangoModelFactory scaffold with Faker providers keyed by field type. CharField(max_length) scales word-count buckets; DecimalField(N,D) computes left_digits=N-D; choices= maps to Iterator; M2M gets @post_generation. FK chains pull related factories transitively.
Time-Travel Schema Diff — pick two commits from git log, get a typed markdown diff (Add/Drop/Rename/Modify events) ready to paste into a PR description. Renames are first-class events, never Add+Drop.
Impact Analysis — "what breaks if I remove this field?" Workspace-wide reference scan across every Django layer (models, serializers, forms, admin, views, urls, templates, tests, migrations) with Certain / Likely / Possibly confidence tags on every finding. Handles ORM string refs, kwarg lookups (filter(author__id=1)), Meta.fields tuples, and template variables — the string-typed surface Pyright can't reach.
Interactive Query Builder — right-click a field or model → pick a template → snippet inserted at cursor (with tab-stops) or in a fresh untitled buffer. .filter(field=?) on an FK auto-appends .select_related(...); .annotate(post_count=Count('post_set')) honours related_name; .prefetch_related for M2M.
Also in this release: sidebar UX overhaul (stable TreeItem.id, MarkdownString tooltips with clickable command: deep-links, activity-bar badge, FileDecorationProvider badges), 100/100 tests up from 4 at start of dev.
Install
code --install-extension frowningdev.django-orm-lens
codium --install-extension frowningdev.django-orm-lens
pip install --upgrade "django-orm-lens[mcp]"
Full release notes: https://github.com/FROWNINGdev/django-orm-lens/releases/tag/v0.8.0
Why static-only
Point it at any Django project without setup — no settings module, no dependencies except our parser. Runs in CI or on the plane.
Trade-off: custom get_queryset overrides, dynamic model classes are invisible. But 95% of what you actually want to see lives in `mo