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
model from being deleted:
class UserProxy(User):
class Meta:
proxy = True
triggers = [
pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete)
]
Default many-to-many “through” models¶
Similar to third-party models, we can also install triggers against default
many-to-many “through” models by using a proxy model.
Here we protect Django User
group relationships from being deleted:
class UserGroupTriggers(User.groups.through):
class Meta:
proxy = True
triggers = [
pgtrigger.Protect(name='protect_deletes', operation=pgtrigger.Delete)
]
Warning
Django doesn’t fully support making proxy models from default through relationships.
Reversing migrations can sometimes throw InvalidBases
errors.
We recommend creating a custom through model when possible. See
the Django docs on making custom “through” models.
Declaring triggers in base models¶
Triggers can be declared in an abstract model and inherited. Here is a base model for soft-delete models:
class BaseSoftDelete(models.Model):
is_active = models.BooleanField(default=True)
class Meta:
abstract = True
triggers = [pgtrigger.SoftDelete(name="soft_delete", field="is_active")]
Keep in mind that Meta
class inheritance follows standard Django convention. If
the child model defines a Meta
class, you will need to inherit the parent’s
Meta
class like so:
class ChildModel(BaseSoftDelete):
class Meta(BaseSoftDelete.Meta):
ordering = ["is_active"]
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.
Warning
There are known issues with installing triggers after migrations that cannot be fixed. For example, reversing migrations can result in trigger installation errors, and race conditions can happen if triggers are installed after the underlying tables have been migrated.
Manual installation, enabling, and disabling¶
The following commands allow one to manually manage trigger installation and are detailed more in the Commands section:
Danger
The commands are are global operations. Use these commands with extreme caution, especially if the triggers are managed by migrations. If you need to temporarily ignore a trigger inside your application, see the Ignoring Execution section.
python manage.py pgtrigger install
: Install triggerspython manage.py pgtrigger uninstall
: Uninstall triggerspython manage.py pgtrigger enable
: Enable triggerspython manage.py pgtrigger disable
: Disable triggerspython manage.py pgtrigger 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. View the Commands section for descriptions of the different
installation states.