Changelog¶
0.2.0 (2026-04-23)¶
Features¶
GeneratedFieldTrigger(auto_refresh=True)(default) —save()andbulk_create()now populate the trigger-computed value onto the in-memory instance without an extra query, by piggybacking aRETURNINGclause on the statement Django already issues.bulk_create(update_conflicts=True)upserts are also covered. Passauto_refresh=Falseto opt out per trigger.QuerySet.update()andbulk_update()remain out of scope — see the guide for why.
0.1.0 (2026-04-12)¶
Initial release. Three trigger classes, plus tooling for computed-field lifecycle management.
Trigger classes¶
UniqueConstraintTrigger— unique constraint with foreign-key traversal, Django expressions, partial conditions,nulls_distinct, deferred timing, and optionalindex=Truebacking.CheckConstraintTrigger— check constraint whoseQcan reference columns on related models viaF("rel__field").GeneratedFieldTrigger— trigger-based generated field that supports foreign-key traversal in its expression and installs reverse triggers on related models so the value stays in sync. Reverse triggers are statement-level with transition tables for efficient bulk cascading.
Computed-field tooling¶
refresh_dependent(queryset)— recompute dependent computed fields after a trigger bypass (raw SQL, disabled triggers, dump restore).refresh_computed_fieldmanagement command — touch rows to force recomputation of specific or allGeneratedFieldTriggerfields.ComputedFieldsReadOnlyAdminMixin— Django admin mixin that auto-marks computed fields as read-only.CycleError— raised at startup ifGeneratedFieldTriggerdependencies form a cycle.
Infrastructure¶
- Django system check
pgconstraints.E001flags triggers accidentally placed inMeta.constraintsinstead ofMeta.triggers.