django-pgtrigger
Postgres trigger support integrated with Django models.
What it is and what it does
django-pgtrigger is a Django integration layer for PostgreSQL triggers. It lets you declare triggers as Python objects in your model's Meta class—such as Protect, ReadOnly, SoftDelete, or FSM—and have them automatically created and managed through Django migrations. Instead of writing raw SQL or relying on Django signals and application logic, you define what should happen at the database level when rows are inserted, updated, or deleted, with optional conditions based on old and new row values.
The package handles the translation from Python trigger definitions to SQL, manages migrations, and provides utilities like pgtrigger.Q and pgtrigger.F to express row conditions without raw SQL. It supports Python 3.10–3.14 and Django 4.2–6.0, and requires PostgreSQL as the database backend. Most use cases avoid custom SQL entirely, though the package allows it for complex scenarios.
Use it for:
- Prevent deletion of active records or enforce soft-delete behavior at the database level.
- Make specific model fields or entire models read-only after creation without application-layer checks.
- Enforce state transitions (e.g., workflow statuses) so invalid transitions are rejected by the database.
- Automatically update search vectors or denormalized columns whenever source data changes.
- Ensure official interfaces are used (e.g., force User.objects.create_user over User.objects.create).
- Track or snapshot model changes for audit logs or versioning without signal handlers.
Worth the install?
AI-flagged interpretation of the facts on this page — verify before relying
django-pgtrigger lets you define PostgreSQL triggers declaratively on Django models, enabling database-level enforcement of constraints, state transitions, and data operations without application code.
Yes, if you use PostgreSQL and Django together. The package is well-maintained, has no known vulnerabilities, and solves real problems—constraints and state enforcement—more reliably at the database level than in application code. The aging maintenance status is not a blocker; the repository is active and the package is stable. Install it when you need database-level triggers; skip it if you use a different database backend.
Install
django-pgtrigger on PyPI
pip
pip install django-pgtriggeruv
uv add django-pgtriggerpoetry
poetry add django-pgtriggerInstalling django-pgtrigger
Before you install
Low friction: pure Python wheel with only django as a runtime dependency. Maintenance status is aging—last release 253 days ago—but the repository remains active with recent commits and no archived status.
License in practice
BSD-3-Clause is permissive; you may use, modify, and distribute this package freely in commercial and private projects with minimal restrictions.
Quickstart
pip install django-pgtrigger
# Add 'pgtrigger' to settings.INSTALLED_APPS
import pgtrigger
from django.db import models
class ProtectedModel(models.Model):
class Meta:
triggers = [
pgtrigger.Protect(name="protect_deletes", operation=pgtrigger.Delete)
]
# Run: python manage.py makemigrations && python manage.py migrate
Requires PostgreSQL as the database backend; django-pgtrigger does not work with other database engines.
Verify before relying
- Performance characteristics when triggers fire on high-volume tables or complex multi-field conditions.
- Compatibility guarantees across the stated Postgres 14–18 range in production environments.
- Whether all common use cases can be expressed without writing raw SQL.
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 | 1 — django |
| Maintenance | aging — 253 days since the last release |
| Last repo commit | |
| First released | |
| Downloads | 1,525,527/month — #3,815 on PyPI (30-day window, as of 2026-08-14) |
| Known vulnerabilities | none known (OSV.dev, checked 2026-08-14) |
Evidence: django_pgtrigger-4.17.0-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-pghistoryTracks all changes to Django models using…
permissive · top 15,000 on PyPI
django-read-onlyPrevents Django database write operations by…
permissive · top 15,000 on PyPI
django-postgres-extraExtends Django's ORM to expose…
permissive · top 15,000 on PyPI
django-pgviews-reduxAdds first-class PostgreSQL view support to…
unclear · top 15,000 on PyPI
alembic_utilsExtends Alembic to autogenerate database…
permissive · top 5,000 on PyPI
django-postgres-copyProvides Django ORM integration for…
permissive · top 5,000 on PyPI
django-pgmigratePrevents migration downtime by detecting and…
permissive · top 5,000 on PyPI
django-soft-deleteAdds soft deletion to Django models by marking…
permissive · top 15,000 on PyPI
django-pg-migration-toolsProvides safer, production-ready Django…
permissive · top 15,000 on PyPI
django-fsm-logAutomatically logs state transitions for Django…
permissive · top 15,000 on PyPI