django-pgtrigger
django-pgtrigger is a Python library that enables the creation and management of PostgreSQL triggers directly from Django models. It simplifies the process of integrating powerful database-level logic, such as protecting operations, enforcing read-only fields, or soft-deleting models, into Django applications. The library is actively maintained, frequently releasing new versions to support the latest Django, Python, and PostgreSQL releases.
Warnings
- breaking Version 4.16.0 dropped support for Python 3.9, and version 4.14.0 dropped support for Postgres 13. Users on these older environments must upgrade their Python or PostgreSQL versions, or pin to an older django-pgtrigger version.
- breaking Version 4.0.0 introduced significant changes to multi-database and registry behavior. The `pgtrigger.get` function was renamed to `pgtrigger.registered`. Management commands (`install`, `uninstall`, `prune`, etc.) now operate on one database at a time and require the `--database` argument for multi-database setups.
- deprecated The `@pgtrigger.register` decorator on models is deprecated since version 3.0. While still functional, the recommended and fully supported way to define triggers is within the `Meta.triggers` list of your Django model.
- gotcha If `settings.PGTRIGGER_MIGRATIONS` is set to `False` to disable migration integration, triggers will not be automatically installed or updated via Django migrations. Manual installation via `python manage.py pgtrigger install` or setting `PGTRIGGER_INSTALL_ON_MIGRATE = True` is then required.
- gotcha Registering triggers programmatically on models from third-party Django applications can create migrations in those apps, leading to potential issues with migration management. Additionally, altering column types used in trigger conditions can cause migration failures if `settings.PGTRIGGER_SCHEMA_EDITOR` is `False`.
Install
-
pip install django-pgtrigger
Imports
- pgtrigger
import pgtrigger
- Protect
from pgtrigger import Protect
- Delete
from pgtrigger import Delete
- Q
from pgtrigger import Q
- F
from pgtrigger import F
Quickstart
import pgtrigger
from django.db import models
class ProtectedModel(models.Model):
name = models.CharField(max_length=100)
class Meta:
app_label = 'myapp'
triggers = [
pgtrigger.Protect(name="prevent_deletes", operation=pgtrigger.Delete)
]
# To see this in action, after adding 'pgtrigger' to INSTALLED_APPS and 'myapp' to your Django project:
# 1. python manage.py makemigrations
# 2. python manage.py migrate
# 3. From a Django shell:
# from myapp.models import ProtectedModel
# ProtectedModel.objects.create(name='Test')
# ProtectedModel.objects.first().delete() # This will raise a ProgrammingError from PostgreSQL