Skip to content

A set of Django Management Commands to help you understand and visualize your project's models

License

Notifications You must be signed in to change notification settings

OmenApps/django-model-info

Repository files navigation

django-model-info

PyPI version Build Status codecov

Instantly understand your Django models' structure and relationships with beautiful, intuitive output.

Working with complex Django projects? Need to quickly understand model relationships and fields? django-model-info is an ideal solution for diving into any Django codebase with confidence.

Why django-model-info?

Four django management commands provide detailed information about your models, relationships, and migrations:

  • Perfect for New Team Members: Quickly understand existing codebases without diving through multiple files.
  • Great for Documentation: Export beautiful HTML or Markdown documentation of your models' structure and relationships.
  • Ideal for Large Projects: Filter by app or model to focus on what matters.
  • Time-Saving: Instantly see model-related information without writing custom scripts.
  • Useful Output: Leverages tools like rich, Markdown, MermaidJS, and Graphviz for beautiful output.

Quick Start

  1. Install the package:
pip install django-model-info
  1. Add to INSTALLED_APPS:
INSTALLED_APPS = (
    ...
    'django_model_info.apps.DjangoModelInfoConfig',
    ...
)

You now have access to four new management commands:

  • modelinfo: Display detailed information about your models
  • modelgraph: Generate a graph of your models and their relationships
  • modelfilters: Understand how to filter queries for complex Django model relationships
  • migrationgraph: Visualize and understand the dependencies between migrations

Example Outputs

modelinfo

HTML Output

python manage.py modelinfo sales -v 3 -o modelinfo.html

Rendered, Raw

Markdown Output

python manage.py modelinfo sales -v 3 -o modelinfo.md

Rendered, Raw

modelfilters

HTML Output

python manage.py modelfilters sales --target-model Customer ShippingAddress --target-field-type CharField -o modelfilters.html

Rendered, Raw

Markdown Output

python manage.py modelfilters sales --target-model Customer ShippingAddress --target-field-type CharField -o modelfilters.md

Rendered, Raw

modelgraph

Analysis Output

python manage.py modelgraph

Output:

Model Graph Analysis
===================

Basic Statistics:
  Models: 5
  Relationships: 4

Isolated Models:
  - sales.bankaccount
  - sales.creditcard

Model Relationships:

  sales.order:
    ← sales.orderitem
      ManyToOneRel (reverse: items)
    → sales.shippingaddress
      ForeignKey (shipping_address)

  sales.orderitem:
    → sales.order
      ForeignKey (order)

  sales.shippingaddress:
    ← sales.order
      ManyToOneRel (reverse: order)

MermaidJS Output

python manage.py modelgraph sales -f mermaid

Result:

```mermaid
graph LR
    common_customer-. "ManyToOneRel<br>reverse: sales_creditcards" .->sales_creditcard
    common_customer["common.customer"]
    sales_creditcard["sales.creditcard"]
    common_customer-. "ManyToOneRel<br>reverse: sales_bankaccounts" .->sales_bankaccount
    common_customer["common.customer"]
    sales_bankaccount["sales.bankaccount"]
    common_customer-. "ManyToOneRel<br>reverse: shipping_addresses" .->sales_shippingaddress
    common_customer["common.customer"]
    sales_shippingaddress["sales.shippingaddress"]
    common_customer-. "ManyToOneRel<br>reverse: orders" .->sales_order
    common_customer["common.customer"]
    sales_order["sales.order"]
    sales_bankaccount== "ForeignKey<br>customer" ===common_customer
    sales_bankaccount["sales.bankaccount"]
    common_customer["common.customer"]
    sales_creditcard== "ForeignKey<br>customer" ===common_customer
    sales_creditcard["sales.creditcard"]
    common_customer["common.customer"]
    sales_order-. "ManyToOneRel<br>reverse: items" .->sales_orderitem
    sales_order["sales.order"]
    sales_orderitem["sales.orderitem"]
    sales_order== "ForeignKey<br>customer" ===common_customer
    sales_order["sales.order"]
    common_customer["common.customer"]
    sales_order== "ForeignKey<br>shipping_address" ===sales_shippingaddress
    sales_order["sales.order"]
    sales_shippingaddress["sales.shippingaddress"]
    sales_orderitem== "ForeignKey<br>order" ===sales_order
    sales_orderitem["sales.orderitem"]
    sales_order["sales.order"]
    sales_shippingaddress-. "ManyToOneRel<br>reverse: order" .->sales_order
    sales_shippingaddress["sales.shippingaddress"]
    sales_order["sales.order"]
    sales_shippingaddress== "ForeignKey<br>customer" ===common_customer
    sales_shippingaddress["sales.shippingaddress"]
    common_customer["common.customer"]
```

Dot Output

python manage.py modelgraph -f dot -o modelgraph.dot

Dot File

Rendered

migrationgraph

python manage.py migrationgraph common sales inventory admin

Output:

[common]
common/0001_initial
	Depends on:
		auth/0001_initial
	Depended upon by:
		sales/0001_initial

[sales]
sales/0001_initial
	Depends on:
		common/0001_initial
		inventory/0001_initial

[inventory]
inventory/0001_initial
	Depended upon by:
		sales/0001_initial

[admin]
admin/0001_initial
	Depends on:
		auth/0001_initial
		contenttypes/0001_initial
	Depended upon by:
		admin/0002_logentry_remove_auto_add
admin/0002_logentry_remove_auto_add
	Depended upon by:
		admin/0003_logentry_add_action_flag_choices
admin/0003_logentry_add_action_flag_choices

_____________________
Migrations Flowchart:

```mermaid
graph TD
    sales_0001_initial["sales/0001"]
    inventory_0001_initial["inventory/0001"]
    auth_0001_initial["auth/0001"]
    contenttypes_0001_initial["contenttypes/0001"]
    common_0001_initial["common/0001"]
    admin_0001_initial["admin/0001"]
    admin_0002_logentry_remove_auto_add["admin/0002"]
    admin_0003_logentry_add_action_flag_choices["admin/0003"]
    admin_0001_initial --> admin_0002_logentry_remove_auto_add
    admin_0002_logentry_remove_auto_add --> admin_0003_logentry_add_action_flag_choices
    inventory_0001_initial --> sales_0001_initial
    auth_0001_initial --> admin_0001_initial
    common_0001_initial --> sales_0001_initial
    contenttypes_0001_initial --> admin_0001_initial
    auth_0001_initial --> common_0001_initial
```

Documentation

For detailed usage and examples, visit our full documentation.

Roadmap

  • List manager and queryset methods
  • Include signals and other model-level methods
  • Add MermaidJS support for visualizing relationships

Contributing

We welcome contributions! This project uses:

Background and Credits

The modelinfo command has been something I have slowly been working on and improving for several years. The original idea behind modelfilters came from observing the underlying functionality in the django-drip-campaigns package and realizing that having a way to list potential filter paths could help developers with building complex queries, though my implementation of those ideas is quite different. The modelgraph command was loosely inspired by existing tools like the graph_models command in django-extensions, but I wanted to provide a more detailed, filterable, and customizable output. The migrationgraph command was inspired by recent discussions I read online about migration graphs and dependencies, but I cannot recall the specific thread/post that sparked the idea.

License

MIT License