django-graphify
Zero-LLM knowledge graph for Django projects.
Inspect models, views, URLs, signals, serializers, admin classes, middleware and settings — all fully offline.
Features
| Feature | Detail |
|---|---|
| Zero LLM | No API keys, no internet required at runtime |
| Two-pass extraction | AST (always works) + Django introspection (richer data) |
| 5 output formats | graph.json, graph.html, GRAPH_REPORT.md, graph.cypher, graph.mermaid |
| Interactive HTML | Force-directed graph, D3 v7 bundled inline — fully offline |
| All node types | Models, Fields, Views (CBV+FBV), URLs, Signals, Serializers, Admin, Middleware, Settings, Apps |
| Rich edges | FK, M2M, OneToOne, URL→View, View→Model, View→Serializer, Signal, Admin, App dependency |
| DRF support | Auto-detected if djangorestframework is installed |
| Single command | python manage.py graphify |
Installation
pip install django-graphify
Add to INSTALLED_APPS:
INSTALLED_APPS = [
...
"django_graphify",
]
Quick start
# Full project graph — all formats
python manage.py graphify
# Single app
python manage.py graphify --app orders
# Custom output dir
python manage.py graphify --out ./docs/graph
# Only json + html
python manage.py graphify --format json html
# Cleaner graph — skip field-level nodes
python manage.py graphify --no-fields
# Only EXTRACTED edges (skip inferred queryset links)
python manage.py graphify --skip-inferred
Output lands in ./graphify-out/ by default:
graphify-out/
├── graph.html ← interactive force-directed graph (open in browser)
├── graph.json ← queryable node/edge data
├── GRAPH_REPORT.md ← god nodes, URL chains, signal wiring, orphans
├── graph.cypher ← Neo4j import
└── graph.mermaid ← Mermaid flowchart (paste into any renderer)
Command reference
| Option | Default | Description |
|---|---|---|
--app APP_LABEL |
all apps | Restrict to one Django app |
--out DIR |
./graphify-out |
Output directory |
--format FMT … |
all |
json html md cypher mermaid |
--no-fields |
off | Exclude field-level nodes |
--skip-inferred |
off | Only EXTRACTED edges |
--no-offline |
off | Use CDN for D3 instead of bundling |
Node types
| Type | What it represents | Color |
|---|---|---|
model |
models.Model subclass |
teal #1D9E75 |
field |
Individual model field | light teal |
view |
CBV or FBV | purple #534AB7 |
url |
path() / re_path() route |
coral #D85A30 |
signal |
Signal sender or receiver | pink #D4537E |
serializer |
DRF Serializer subclass |
amber #BA7517 |
admin |
ModelAdmin class |
gray |
middleware |
Entry in MIDDLEWARE setting |
blue #378ADD |
app |
Entry in INSTALLED_APPS |
green #639922 |
setting |
Top-level settings key | dark gray |
Edge types
| Relation | Example | Tag |
|---|---|---|
fk |
Order.customer → User |
EXTRACTED |
m2m |
Post.tags → Tag |
EXTRACTED |
one_to_one |
Profile.user → User |
EXTRACTED |
url_to_view |
/api/orders/ → OrderListView |
EXTRACTED |
view_to_model |
OrderListView → Order |
INFERRED |
view_to_serializer |
OrderListView → OrderSerializer |
EXTRACTED |
serializer_to_model |
OrderSerializer → Order |
EXTRACTED |
signal_sender_receiver |
post_save → send_welcome_email |
EXTRACTED |
admin_to_model |
UserAdmin → User |
EXTRACTED |
app_dependency |
INSTALLED_APPS order | EXTRACTED |
model_has_field |
Order → Order.status |
EXTRACTED |
Every edge is tagged EXTRACTED (found in source), INFERRED (confident guess), or AMBIGUOUS (needs review). INFERRED edges carry a confidence score (0–1).
Python API
You can also drive extraction programmatically:
from pathlib import Path
from django_graphify.graph import GraphBuilder
from django_graphify.extractors import ModelExtractor, ViewExtractor
from django_graphify.exporters import JsonExporter, HtmlExporter
builder = GraphBuilder(project_name="myproject")
root = Path("/path/to/project")
for ExtractorClass in [ModelExtractor, ViewExtractor]:
extractor = ExtractorClass(root)
nodes, edges = extractor.ast_extract()
builder.add_nodes(nodes)
builder.add_edges(edges)
nodes, edges = extractor.introspect()
builder.add_nodes(nodes)
builder.add_edges(edges)
JsonExporter(builder).export(Path("./out"))
HtmlExporter(builder).export(Path("./out"))
# Query
node = builder.get_node("orders.Order")
neighbours = builder.get_neighbours("orders.Order")
path = builder.shortest_path("orders.Order", "users.User")
gods = builder.god_nodes(top_n=5)
orphans = builder.orphan_nodes()
graph.json schema
{
"meta": {
"project": "myproject",
"django_version": "4.2.7",
"generated_at": "2025-04-29T10:00:00Z",
"node_count": 142,
"edge_count": 89
},
"nodes": [
{
"id": "orders.Order",
"type": "model",
"label": "Order",
"app": "orders",
"file": "orders/models.py",
"line": 14,
"tag": "EXTRACTED",
"confidence": 1.0,
"meta": { "db_table": "orders_order", "abstract": false }
}
],
"edges": [
{
"source": "orders.Order",
"target": "users.User",
"relation": "fk",
"tag": "EXTRACTED",
"confidence": 1.0,
"meta": { "field": "customer" }
}
]
}
How it works
Pass 1 — AST (always runs):
Uses Python's ast module to walk every .py file. No Django import required. Extracts class names, base classes, field assignments, decorators. Works even if the project can't be fully imported.
Pass 2 — Django introspection (runs when Django is configured):
Uses django.apps.apps.get_models(), django.conf.settings, and DRF's serializer registry to enrich Pass 1 nodes with concrete field types, FK targets, choices, related_name, middleware ordering, and installed app paths. Gracefully skipped if DJANGO_SETTINGS_MODULE isn't set.
Requirements
- Python 3.10+
- Django 3.2+
networkx >= 3.0djangorestframework(optional — DRF extraction auto-detected)
Author
Yogesh Chauhan — AI and Django engineer, India.
License
MIT — see LICENSE.
Release files for django-graphify 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django_graphify-0.1.1.tar.gz | 35.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_graphify-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 74.8 kB
Release files / django_graphify-0.1.1.tar.gz
| Download URL | django_graphify-0.1.1.tar.gz |
|---|---|
| Size | 35.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5bb7e1fc83ce38b08aef876d6369df607670f671e38a04cda8b1196f7d1ecc66
|
|
BLAKE2b-256 checksum How to use checksums |
340a3eb34bceb44585805fc6233761c7e60b95a415b98989701ecfb912761845
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|
Release files / django_graphify-0.1.1-py3-none-any.whl
| Download URL | django_graphify-0.1.1-py3-none-any.whl |
|---|---|
| Size | 39.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7d417e695ae927d292387a6eae8f6647406ce72f26b9d7296c8cc9b4333d8f54
|
|
BLAKE2b-256 checksum How to use checksums |
ddf4620da1c03afd9184af175bb833c4347a2660fcf3bc5bae21bf2b8c096d88
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|