Advanced Installation¶
Third-party models¶
Install triggers on third-party models by declaring them on a proxy model.
For example, here we protect Django’s User
models from being deleted:
class UserProxy(User):
class Meta:
proxy = True
triggers = [
pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete)
]
Note that this syntax does not work for default many-to-many “through” models. See the next section for details.
Default many-to-many “through” models¶
When defining a many-to-many relationship, Django uses a separate relationship model, called the “through” model. If you want to install triggers for the default through model, you will need to define them on an unmanaged model that uses the database table of the through model.
Here we protect Django User
group relationships from being deleted:
class UserGroupTriggers(models.Model):
class Meta:
managed = False
db_table = User.groups.through._meta.db_table
triggers = [
pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete)
]
Although django-pgtrigger
allows installing triggers against unmanaged models,
we recommend only using this feature for this specific use case.
Note
If a third-party through model is used, be sure to set the dependencies
of the migration to depend on the third-party app’s last migration.
Programmatically registering triggers¶
Triggers can be registered programmatically with pgtrigger.register
.
It can be used as a decorator on a model or called like so:
# Register a protection trigger for a model
pgtrigger.register(pgtrigger.Protect(...))(MyModel)
Warning
Although triggers can be registered programmatically, we don’t recommend doing this except for advanced use cases. Registering a trigger to a model of a third-party app will create migrations in that app. This could result in migrations not being added to your codebase, which can result in triggers not being installed.
Turning off migration integration¶
django-pgtrigger
patches Django’s migration system so that triggers are installed
and updated in migrations. If this is undesirable, you can
disable the migration integration by setting settings.PGTRIGGER_MIGRATIONS
to
False
. After this, you are left with two options:
Manually install triggers with the commands detailed in the next section.
Run trigger installation after every
python manage.py migrate
by settingsettings.PGTRIGGER_INSTALL_ON_MIGRATE
toTrue
. Keep in mind that reversing migrations can cause issues when installing triggers this way.
Manual installation, enabling, and disabling¶
Warning
Installing, uninstalling, enabling, and disabling triggers are global operations
that call ALTER
on the table. These should never be called in application code,
and they will also interfere with migrations. Only use them when absolutely necessary or
when manually managing trigger installations outside of migrations.
If you want to temporarily ignore a trigger in an application, see the
Ignoring Execution section.
Sometimes one may need to manage installed triggers outside of the Django migration system
or turn off migrations by setting settings.PGTRIGGER_MIGRATIONS
to False
.
The following functions manage trigger installation, and each one has an associated management
command in the Commands section:
pgtrigger.install
: Install triggerspgtrigger.uninstall
: Uninstall triggerspgtrigger.enable
: Enable triggerspgtrigger.disable
: Disable triggerspgtrigger.prune
: Uninstall triggers created bydjango-pgtrigger
that are no longer in the codebase.
Showing installation status¶
Use python manage.py pgtrigger ls
to see the installation status of individual triggers
or all triggers at once.
Triggers can be in one of three installation states: INSTALLED
, UNINSTALLED
, or PRUNED
.
When in a PRUNED
state, the trigger is installed but no longer exists in the application.
Triggers are also either ENABLED
or DISABLED
. Triggers are enabled by default unless a user
explicitly disables it after installation. Once disabled, triggers must be enabled
again to run.