django-pghistory
History tracking for Django and Postgres
What it is and what it does
django-pghistory is a Django package that automatically records every change to your models by installing PostgreSQL triggers on the underlying tables. Instead of instrumenting your application code, it captures inserts, updates, and bulk operations—even raw SQL changes—at the database level and stores them in dynamically-created event models that mirror your original model's fields. You decorate a model with `@pghistory.track()`, run migrations, and the system handles the rest: every modification is logged with metadata fields like `pgh_obj` (the tracked object ID) and timestamps.
The package includes admin integration and middleware for attaching application context (such as the logged-in user) to events without extra database queries. It supports selective field tracking, conditional event storage based on field transitions, and aggregation across multiple event models. Since it relies on PostgreSQL triggers rather than application-level hooks, it captures changes regardless of how they reach the database—ORM saves, bulk updates, or direct SQL all get tracked.
Use it for:
- Audit compliance: maintain a tamper-resistant record of all model changes for regulatory requirements.
- Soft deletes and recovery: revert models to previous versions or implement logical deletion with full history.
- User activity tracking: attach context like user ID to each change for accountability and debugging.
- Data debugging: trace the sequence of field changes to diagnose unexpected model states.
- Bulk operation auditing: capture changes from bulk operations or raw SQL that ORM hooks would miss.
Worth the install?
AI-flagged interpretation of the facts on this page — verify before relying
Tracks all changes to Django models using PostgreSQL triggers, storing a complete audit trail without modifying application code.
Yes. The package is actively maintained, has low install friction, carries a permissive license, and solves a real problem—reliable audit trails without application code changes. It's well-suited for Django projects using PostgreSQL where compliance, debugging, or recovery capabilities matter. No known security vulnerabilities. Primary constraint is PostgreSQL dependency; it will not work with other databases.
Install
django-pghistory on PyPI
pip
pip install django-pghistoryuv
uv add django-pghistorypoetry
poetry add django-pghistoryInstalling django-pghistory
Before you install
Low friction install with a pure-Python wheel. Actively maintained as of 2026-02-17 with 540 repository stars. Requires only django and django-pgtrigger as runtime dependencies.
License in practice
BSD-3-Clause permissive license allows commercial and private use with minimal restrictions.
Quickstart
pip install django-pghistory
import pghistory
from django.db import models
@pghistory.track()
class TrackedModel(models.Model):
int_field = models.IntegerField()
text_field = models.TextField()
m = TrackedModel.objects.create(int_field=1, text_field="hello")
m.int_field = 2
m.save()
print(m.events.values("pgh_obj", "int_field"))
Requires PostgreSQL and Django; add pghistory and pgtrigger to INSTALLED_APPS after installation.
Verify before relying
- Whether the package's trigger-based approach has measurable performance impact on high-volume write workloads
- How context attachment and metadata storage scale with concurrent application instances
Package facts
| License | BSD-3-Clause (permissive) |
| Python support | supports the current Python release (<4,>=3.10.0) |
| Install friction | low — pure-Python wheel |
| Runtime dependencies | 2 — django, django-pgtrigger |
| Maintenance | actively maintained — 178 days since the last release |
| Last repo commit | |
| First released | |
| Downloads | 783,657/month — #5,074 on PyPI (30-day window, as of 2026-08-14) |
| Known vulnerabilities | none known (OSV.dev, checked 2026-08-14) |
Evidence: django_pghistory-3.9.2-py3-none-any.whl
Tags
More Database packages
psycopg2-binary is a PostgreSQL database…
copyleft · top 1,000 on PyPI
redisPython client library for connecting to and…
permissive · top 1,000 on PyPI
ydbYDB Python SDK is the official client library…
permissive · top 1,000 on PyPI
snowflake-connector-pythonConnects Python applications to Snowflake data…
permissive · top 1,000 on PyPI
sqlparsesqlparse tokenizes SQL text into a tree of…
permissive · top 1,000 on PyPI
dbt-adaptersProvides base adapter protocols and shared…
permissive · top 1,000 on PyPI
django-easy-auditLogs every CRUD operation, authentication…
copyleft · top 15,000 on PyPI
django-pgtriggerdjango-pgtrigger lets you define PostgreSQL…
permissive · top 5,000 on PyPI
django-auditlogdjango-auditlog logs changes to Django model…
permissive · top 5,000 on PyPI
django-reversiondjango-reversion adds version control to Django…
permissive · top 5,000 on PyPI
django-dirtyfieldsTracks which fields on a Django model instance…
permissive · top 15,000 on PyPI
SQLAlchemy-ContinuumSQLAlchemy-Continuum adds automatic versioning…
permissive · top 5,000 on PyPI
django-postgres-copyProvides Django ORM integration for…
permissive · top 5,000 on PyPI
django-crumDjango-CRUM stores the current request and user…
permissive · top 15,000 on PyPI
django-fsm-logAutomatically logs state transitions for Django…
permissive · top 15,000 on PyPI
django-pgactivityProvides Django management commands and…
permissive · top 5,000 on PyPI