๐งพ django-annotate
Annotate Django model files with schema information (fields, indexes, and foreign keys), inspired by the annotaterb project for Rails.
โจ Features
- Adds
# == Schema Information
blocks above each model class
- Supports:
- Field types
- Indexes (including unique constraints)
- Foreign key relationships
- Works on monolithic or multi-file model setups
- CLI support via Django's
manage.py
๐๏ธ Database Support
Currently, django-annotate
only supports PostgreSQL databases. This is because it uses PostgreSQL-specific system tables (pg_*
) to introspect the database schema. Support for other databases (MySQL, SQLite) is planned for future releases.
Requirements
- PostgreSQL database
- Django project configured to use PostgreSQL as the database backend
- Appropriate database permissions to query system tables
- Standard Django ORM models (inheriting from
django.db.models.Model
)
If you're using a different database backend, you'll need to either:
- Switch to PostgreSQL
- Wait for support for your database to be added
- Contribute support for your database backend
๐ฆ Installation
pip install django-annotate
poetry add django-annotate
โ๏ธ Setup
No configuration required โ just install and run. If you want to run it via Django's CLI, ensure django_annotate
is on your Python path (you don't need to add it to INSTALLED_APPS
unless you want auto-discovery inside Django).
Then run:
python manage.py annotate_models
This will annotate models in all installed apps (excluding any apps listed in ignore_apps
in your configuration).
To annotate a specific app:
python manage.py annotate_models --app=myapp
๐ Auto-Annotation After Migrations
By default, model annotation runs automatically after every migration in development environments. This helps keep your model files up-to-date with your database schema.
Auto-annotation is disabled by default in production environments when DEBUG = False
(typical in production).
To control auto-annotation behavior, you can configure the following settings in your .django_annotate.yml
file:
skip_on_migrate: false
force: false
frozen: false
๐งช Example Output
class Organization(models.Model):
name = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
class User(models.Model):
organization = models.ForeignKey(Organization, on_delete=models.CASCADE)
email = models.EmailField(unique=True)
full_name = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField(blank=True)
class Project(models.Model):
name = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
members = models.ManyToManyField(User, related_name="projects")
๐ License
MIT ยฉ 2025 Chris Davis
โ๏ธ Configuration
You can configure django-annotate
by creating a .django_annotate.yml
file in your project root. Here's a comprehensive list of all available configuration options:
position: before
show_indexes: true
show_foreign_keys: true
with_column_comments: true
include_version: false
timestamp: false
ignore_models: []
ignore_apps: []
ignore_columns: []
skip_on_migrate: false
force: false
frozen: false
Quick Start
For most projects, you can start with a minimal configuration file. For example, to control auto-annotation behavior:
skip_on_migrate: false
force: false
frozen: false
All other settings will use sensible defaults. You can add more settings as needed.
Production Safety
By default, django-annotate
will not run in production environments. This is enforced by:
- Not running when
DEBUG = False
(typical in production)
- Respecting the
frozen
setting in your configuration
To ensure safety in production, add this to your .django_annotate.yml
:
frozen: true
The recommended workflow is:
- Run migrations and annotations locally
- Commit the annotated files to version control
- Deploy the committed files to production