django-model-utils

Reusable Django model mixins, fields, and managers for timestamps, soft deletes, status tracking, and change detection.

Library
PyPI
v5.0.0
2,759stars
BSD 3-Clause License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
61/100Good
Development Activity48
Maintenance20
Community76
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
81/100Excellent
Architecture78
Code Quality85
Innovation72
Learning Curve88

django-model-utils is a Jazzband-maintained collection of Django model mixins, fields, and manager/queryset utilities that fill in patterns that come up in almost every Django project — timestamping, soft deletion, status workflows, field change tracking, and multi-table-inheritance queries — so teams don’t reimplement them per-app.

Rather than a single opinionated ORM extension, it is a toolbox: pull in only the mixins and fields you need, such as TimeStampedModel for created/modified timestamps, FieldTracker for dirty-checking, or InheritanceManager for subclass-aware queries, and compose them onto your existing Django models. The project has been actively maintained since 2009, supports current Django (4.2-5.2) and Python (3.10-3.14) versions, and ships full type stubs (py.typed) for use with django-stubs and mypy.

What You Get

  • Abstract model mixins (TimeStampedModel, TimeFramedModel, StatusModel, SoftDeletableModel, UUIDModel) to compose into your own models
  • Custom fields (StatusField, MonitorField, SplitField, UUIDField, UrlsafeTokenField, AutoCreatedField, AutoLastModifiedField)
  • Change tracking via FieldTracker/ModelTracker for detecting per-field diffs between saves
  • Manager and queryset helpers (QueryManager, InheritanceManager, SoftDeletableManager) for common query patterns
  • A Choices helper for structured, human-readable Django choices, including grouped choices

Common Use Cases

  • Adding created/modified timestamps to models without writing custom save() logic
  • Implementing soft-delete instead of destructive deletes
  • Building status/workflow fields with automatic per-status querysets
  • Tracking which fields changed on a model instance since it was loaded
  • Querying multi-table-inherited models and getting back the correct subclass

Under The Hood

Architecture The package has no central registry class; behavior is added through mixin composition and Django signal hooks rather than a monolithic base. models.py defines abstract Model mixins and dynamically injects per-status managers by connecting to Django’s class_prepared signal (add_status_query_managers, add_timeframed_query_manager); fields.py defines custom Field subclasses following Django’s Field API (overriding pre_save, get_default, contribute_to_class); managers.py composes Manager/QuerySet behavior via multiple inheritance (e.g. SoftDeletableManager built from SoftDeletableManagerMixin and models.Manager); and tracker.py implements a descriptor-based FieldTracker that installs wrapper descriptors on class attributes to intercept get/set and record per-field state, hooked into Django’s init signals. Because the package is purely additive on top of Django’s own Model/Field/Manager/QuerySet base classes, the main integration risk is Django’s own API changes across versions, which the maintainers manage by testing a matrix of supported Django releases (4.2-5.2).

Tech Stack A pure Python package with no build step beyond setuptools, using setuptools_scm to derive versions from git tags; the only runtime dependency is Django itself (>=4.2). Development and test tooling includes tox for running the full Python/Django version matrix, pytest with a dedicated Django test settings module, time-machine for freezing time in tests, sphinx for ReadTheDocs-hosted documentation, twine for publishing, and mypy with django-stubs for static typing (mypy.ini, py.typed). CI runs on GitHub Actions: a test workflow exercises the full Python 3.10-3.14 by Django version matrix against a real Postgres service container, a release workflow handles PyPI publishing, and an issue-manager workflow triages stale issues, consistent with the project’s Jazzband shared-maintainer model.

Code Quality The tests directory mirrors the module layout (fields, models, managers, choices, inheritance, miscellaneous) and runs against a live Postgres service in CI rather than sqlite only, giving reasonably realistic coverage of edge cases like unique constraints. Source is fully type-annotated with postponed evaluation of annotations, explicit generics bound to Django’s Model type, and TypeVars, ships py.typed, and is checked with mypy against django-stubs. Naming is consistent and Django-idiomatic throughout. Import sorting is enforced via isort with a black-compatible profile; no additional linter configuration was found in the repository root.

API Design The public API favors small, single-purpose mixins and fields that are opted into individually rather than an all-or-nothing base class, keeping integration low-friction; adding a mixin like TimeStampedModel to a model’s bases is typically a one-line change. FieldTracker in particular offers an ergonomic API for a problem most Django developers otherwise hand-roll, letting code check whether a field has changed or read its previous value directly from the tracked instance. Documentation is thorough and split per concern across several dedicated pages and hosted on ReadTheDocs, with docstrings on nearly every public class. Individually, the mixins follow well-known Django patterns rather than introducing new concepts, but the breadth and long-running maturity of the collection is the main value over hand-rolling each one.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search