Declarative model lifecycle hooks.
Project description
Django Lifecycle Hooks
This project provides a @hook decorator as well as a base model and mixin to add lifecycle hooks to your Django models. Django's built-in approach to offering lifecycle hooks is Signals. However, my team often finds that Signals introduce unnecessary indirection and are at odds with Django's "fat models" approach.
Django Lifecycle Hooks supports:
- Python 3.8, 3.9, 3.10, 3.11, 3.12, 3.13 and 3.14
- Django 4.2, 5.0, 5.2 and 6.0
In short, you can write model code like this:
from django_lifecycle import LifecycleModel, hook, BEFORE_UPDATE, AFTER_UPDATE
from django_lifecycle.conditions import WhenFieldValueIs, WhenFieldValueWas, WhenFieldHasChanged
class Article(LifecycleModel):
contents = models.TextField()
updated_at = models.DateTimeField(null=True)
status = models.ChoiceField(choices=['draft', 'published'])
editor = models.ForeignKey(AuthUser)
@hook(BEFORE_UPDATE, WhenFieldHasChanged("contents", has_changed=True))
def on_content_change(self):
self.updated_at = timezone.now()
@hook(
AFTER_UPDATE,
condition=(
WhenFieldValueWas("status", value="draft")
& WhenFieldValueIs("status", value="published")
)
)
def on_publish(self):
send_email(self.editor.email, "An article has published!")
Instead of overriding save and __init__ in a clunky way that hurts readability:
# same class and field declarations as above ...
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._orig_contents = self.contents
self._orig_status = self.status
def save(self, *args, **kwargs):
if self.pk is not None and self.contents != self._orig_contents:
self.updated_at = timezone.now()
super().save(*args, **kwargs)
if self.status != self._orig_status:
send_email(self.editor.email, "An article has published!")
Documentation: https://rsinger86.github.io/django-lifecycle
Source Code: https://github.com/rsinger86/django-lifecycle
Changelog
See Changelog
Testing
Tests are found in a simplified Django project in the /tests folder. Install the project requirements and do ./manage.py test to run them.
License
See License.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_lifecycle-1.2.6.tar.gz.
File metadata
- Download URL: django_lifecycle-1.2.6.tar.gz
- Upload date:
- Size: 12.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
94289e26bafcf6cad49d219d2489a1790c07e5d133e9aa335ccfdc20cbf07115
|
|
| MD5 |
c6e8319869a4beb8747fe41059d63637
|
|
| BLAKE2b-256 |
f988b6ecaec4a73333e1f8fedf0dd21175814bb8cd32a4853a8332f59263f49a
|
File details
Details for the file django_lifecycle-1.2.6-py3-none-any.whl.
File metadata
- Download URL: django_lifecycle-1.2.6-py3-none-any.whl
- Upload date:
- Size: 15.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2f1c86c9803117070bc112ea92819bc12c5c961ace4f00d960b2b87002c07d73
|
|
| MD5 |
50c074730ffca83450fd9d6bd53cb113
|
|
| BLAKE2b-256 |
5c0bc0e4c148e93374acd5a129d434472004b07a123bca907ee8c06035bc40b8
|