Django Lifecycle

1.2.7 · active · verified Fri Apr 17

Django Lifecycle is a Python library that provides declarative lifecycle hooks for Django models. It allows developers to define methods that run automatically before or after database operations (e.g., save, delete, create, update) or when specific model field values change, using simple decorators. The current version is 1.2.7, and it maintains an active release cadence with frequent bug fixes and feature enhancements.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to define a Django model with `LifecycleModelMixin` and use the `@hook` decorator for various events. It includes examples for capitalizing a name `BEFORE_SAVE`, logging a price change `AFTER_UPDATE` when the `price` field `has_changed`, and sending a low stock notification `BEFORE_SAVE` when `stock` falls within a specific range using `is_greater_than` and `is_less_than` conditions, and generating a SKU on `POST_INIT`.

import os
from django.db import models
from django_lifecycle import LifecycleModelMixin, hook, BEFORE_SAVE, AFTER_UPDATE, POST_INIT
from django_lifecycle.conditions import is_greater_than, is_less_than

# NOTE: This example assumes Django settings are configured, e.g., via manage.py shell
# or a test environment.

class Product(LifecycleModelMixin, models.Model):
    name = models.CharField(max_length=255)
    price = models.DecimalField(max_digits=10, decimal_places=2, default=0)
    stock = models.IntegerField(default=0)
    sku = models.CharField(max_length=100, unique=True, blank=True, null=True)

    @hook(POST_INIT)
    def on_init(self):
        if not self.sku:
            self.sku = f"SKU-{os.urandom(4).hex().upper()}"

    @hook(BEFORE_SAVE)
    def ensure_name_capitalized(self):
        self.name = self.name.capitalize()

    @hook(AFTER_UPDATE, when='price', has_changed=True)
    def log_price_change(self):
        print(f"Product '{self.name}' (SKU: {self.sku}) price changed from {self.initial_value('price')} to {self.price}")

    @hook(BEFORE_SAVE, when='stock', is_greater_than=0, is_less_than=10)
    def notify_low_stock(self):
        print(f"WARNING: Stock for '{self.name}' (SKU: {self.sku}) is critically low ({self.stock})!")

    def __str__(self):
        return self.name

# Example Usage (run in a Django shell or similar):
# from your_app.models import Product # Replace 'your_app'
#
# p1 = Product.objects.create(name="keyboard", price=75.00, stock=20)
# print(f"Created: {p1.name} with SKU: {p1.sku}") # SKU will be auto-generated on POST_INIT
#
# p1.price = 80.50
# p1.save() # Triggers log_price_change
#
# p1.stock = 5
# p1.save() # Triggers notify_low_stock
#
# p2 = Product(name="mouse", price=25.00, stock=15)
# p2.save() # Triggers ensure_name_capitalized and on_init (for sku)
# print(f"Created: {p2.name} with SKU: {p2.sku}")

view raw JSON →