skillfed

django-pgtrigger

Postgres trigger support integrated with Django models.

django-pgtrigger v4.17.0 1.5M downloads/30d#3,815 on PyPI644
Permissive license BSD-3-Clause AGING released

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-pgtrigger

uv

uv add django-pgtrigger

poetry

poetry add django-pgtrigger

Installing 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

Framework :: DjangoFramework :: Django :: 4.2Framework :: Django :: 5.0Framework :: Django :: 5.1Framework :: Django :: 5.2Framework :: Django :: 6.0Intended Audience :: DevelopersLicense :: OSI Approved :: BSD LicenseOperating System :: OS IndependentProgramming Language :: PythonProgramming Language :: Python :: 3Programming Language :: Python :: 3 :: OnlyProgramming Language :: Python :: 3.10Programming Language :: Python :: 3.11Programming Language :: Python :: 3.12Programming Language :: Python :: 3.13Programming Language :: Python :: 3.14

Tags

postgres triggers djangodatabase constraints django modelssoft delete django postgresfield state transitions databaseprotect delete rows postgresread-only fields database leveltrigger automation django
postgres-triggersdatabase-constraintsdjango-integration

More Database packages