def setup(self, event_model): insert_trigger = pghistory.trigger.Event( event_model=event_model, label=self.label, name=_get_name_from_label(f'{self.label}_insert'), snapshot='NEW', when=pgtrigger.After, operation=pgtrigger.Insert, ) condition = pgtrigger.Q() for field in event_model._meta.fields: if hasattr(event_model.pgh_tracked_model, field.name): condition |= pgtrigger.Q(**{ f'old__{field.name}__df': pgtrigger.F(f'new__{field.name}') }) update_trigger = pghistory.trigger.Event( event_model=event_model, label=self.label, name=_get_name_from_label(f'{self.label}_update'), snapshot='NEW', when=pgtrigger.After, operation=pgtrigger.Update, condition=condition, ) pgtrigger.register(insert_trigger, update_trigger)(event_model.pgh_tracked_model)
field = models.CharField(max_length=16) class CharPk(models.Model): custom_pk = models.CharField(primary_key=True, max_length=32) @pgtrigger.register( pgtrigger.Protect(name='protect_delete', operation=pgtrigger.Delete), pgtrigger.Trigger( name='protect_misc_insert', when=pgtrigger.Before, operation=pgtrigger.Insert, func="RAISE EXCEPTION 'no no no!';", condition=pgtrigger.Q(new__field='misc_insert'), ), ) class TestTrigger(models.Model): """ For testing triggers """ field = models.CharField(max_length=16) int_field = models.IntegerField(default=0) dt_field = models.DateTimeField(default=timezone.now) nullable = models.CharField(null=True, default=None, max_length=16) fk_field = models.ForeignKey('auth.User', null=True, on_delete=models.CASCADE) char_pk_fk_field = models.ForeignKey(CharPk,
import pghistory class UntrackedModel(models.Model): untracked = models.CharField(max_length=64) @pghistory.track( pghistory.Snapshot('snapshot'), model_name='CustomModelSnapshot', related_name='snapshot', ) @pghistory.track( pghistory.AfterUpdate( 'int_field_updated', condition=pgtrigger.Q( old__int_field__df=pgtrigger.F('new__int_field')), )) class CustomModel(models.Model): """ For testing history tracking with a custom primary key and custom column name """ my_pk = models.UUIDField(primary_key=True) int_field = models.IntegerField(db_column='integer_field') @pghistory.track(pghistory.Snapshot('snapshot'), related_name='snapshot') class UniqueConstraintModel(models.Model): """For testing tracking models with unique constraints"""
@pgtrigger.register( pgtrigger.Protect(operation=(pgtrigger.Update | pgtrigger.Delete))) class AppendOnly(models.Model): """This model can only be appended. The ``pgtrigger.Protect`` trigger protects the update or delete operations from happening, making this an "append-only" model. """ int_field = models.IntegerField() @pgtrigger.register( pgtrigger.Protect(operation=pgtrigger.Update, condition=pgtrigger.Q( old__created_at__df=pgtrigger.F('new__created_at')))) class ReadOnlyField(models.Model): """ The "created_at" field cannot be updated (i.e. a read-only field). Updates to other fields will pass, but any updates to created_at will result in an error """ created_at = models.DateTimeField(auto_now_add=True) int_field = models.IntegerField() @pgtrigger.register(pgtrigger.SoftDelete(field='is_active', value=False)) class SoftDelete(models.Model): """ This model cannot be deleted. When a user tries to delete it, the