Skip to main content

Django Lifecycle Hooks

Package version PyPI status Python versions Django versions

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.

Release files for django-lifecycle 1.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-lifecycle 1.3.0
File Size Uploaded
django_lifecycle-1.3.0.tar.gz 12.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-lifecycle 1.3.0
File Interpreter ABI Platform
django_lifecycle-1.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 28.5 kB

Release files / django_lifecycle-1.3.0.tar.gz

Download URL django_lifecycle-1.3.0.tar.gz
Size 12.8 kB
Tags Source
SHA-256 checksum
How to use checksums
9e8b6f7105b074b198dfa19424b7ddf94c067cae6a8baba2cdc6120eb79f9120
BLAKE2b-256 checksum
How to use checksums
a3bd4bb5e6cda63ded99c9f68578f6271f397c44e7fd7e1806227d6dd20432f7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.25

Release files / django_lifecycle-1.3.0-py3-none-any.whl

Download URL django_lifecycle-1.3.0-py3-none-any.whl
Size 15.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8c706c7c7d157b1df62e825e01c6f2d14a98d9b298217409ee5e015d93fc73e5
BLAKE2b-256 checksum
How to use checksums
47f258da8e552d6f74019c8c22624411d336a9b930b99705cefed751c5a4a8f2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.25

Release history Release notifications | RSS feed

This release

1.3.0 This release

2 release files

1.2.7

2 release files

1.2.6

2 release files

1.2.5

2 release files

1.2.4

2 release files

1.2.3

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.2

1 release file

1.0.1

1 release file

1.0.0

1 release file

0.9.6

1 release file

0.9.5

1 release file

0.9.4

1 release file

0.9.3

1 release file

0.9.2

1 release file

0.9.1

1 release file

0.9.0

1 release file

0.8.1

1 release file

0.8.0

1 release file

0.7.7

1 release file

0.7.6

1 release file

0.7.5

1 release file

0.7.1

1 release file

0.7.0

1 release file

0.6.1

1 release file

0.6.0

1 release file

0.5.0

1 release file

0.4.2

1 release file

0.4.1

1 release file

0.4.0

1 release file

0.3.2

1 release file

0.3.1

1 release file

0.3.0

1 release file

0.2.5

1 release file

0.2.4

1 release file

0.2.3

1 release file

0.2.2

1 release file

0.2.1

1 release file

0.2.0

1 release file

0.1.3

1 release file

0.1.2

1 release file

0.1.1

1 release file

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page