Django Model Utils
Django Model Utils is a comprehensive Python library that provides a collection of abstract base classes, managers, fields, and utilities designed to simplify common Django model patterns. It includes features like `StatusField` for managing object states, `TimeStampedModel` for automatic creation/modification timestamps, `SoftDeletableModel` for logical deletion, and `FieldTracker` for monitoring field changes. The current version is 5.0.0, and it generally keeps pace with Django's major release cycle for compatibility.
Warnings
- breaking The `SaveSignalHandlingModel` has been removed. If you used this abstract base class to temporarily disable signals during a save operation, you will need to refactor your code. This model was removed in version 4.4.0 due to maintainability concerns with its modified `Model.save_base()` method.
- breaking The `JoinQueryset.get_quoted_query()` method was removed in version 4.5.1. If your code directly invoked this method, it will now fail.
- breaking Version 4.0.0 dropped support for Python 2.7 and Django 1.11. Additionally, it removed internal usage of the `six` compatibility library.
- breaking Behavioral changes to `FieldTracker` in version 4.1.0 mean it now correctly marks fields as not changed after `refresh_from_db` and respects `update_fields` when saving. It also resets states after `pre_save()` signals instead of `save()` signals.
- deprecated The `ModelTracker` was deprecated in favor of `FieldTracker` due to serious flaws in handling `ForeignKey` fields, leading to potentially many extra database queries.
- deprecated For `SoftDeletableModel`, relying on the default `objects` manager to filter out not-deleted instances is deprecated. The `objects` manager will include deleted objects in a future release.
- gotcha In version 5.0.0, the `MonitorField` now defaults to `None` when nullable and no default is provided, instead of `django.utils.timezone.now`.
Install
-
pip install django-model-utils
Imports
- FieldTracker
from model_utils import FieldTracker
- StatusField
from model_utils.fields import StatusField
- TimeStampedModel
from model_utils.models import TimeStampedModel
- SoftDeletableModel
from model_utils.models import SoftDeletableModel
- Choices
from model_utils import Choices
Quickstart
from django.db import models
from model_utils import FieldTracker
class Post(models.Model):
title = models.CharField(max_length=100)
body = models.TextField()
tracker = FieldTracker()
def save(self, *args, **kwargs):
# Example of using FieldTracker in a save method
super().save(*args, **kwargs)
if self.tracker.has_changed('title'):
print(f"Title changed from '{self.tracker.previous('title')}' to '{self.title}'")
# Example usage (requires Django setup and database interaction)
# post = Post.objects.create(title='Initial Title', body='Some body content')
# post.title = 'Updated Title'
# post.save()
# print(post.tracker.changed()) # Shows all changed fields and their previous values