django-deprecate-fields

Deprecate Django model fields safely and remove them later without breaking production.

Library
PyPI
v0.2.3
196stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
44/100Fair
Development Activity24
Maintenance4
Community68
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
68/100Good
Architecture62
Code Quality68
Innovation58
Learning Curve82

django-deprecate-fields provides a deprecate_field() wrapper for Django model fields that formalizes a safe, three-step deletion process: mark the field as deprecated, deploy that change everywhere, then delete the field entirely. Wrapping a field automatically makes it nullable during makemigrations/migrate while replacing runtime access to the field with a descriptor that logs a DeprecationWarning (or optionally raises) whenever code still reads or writes it.

This lets teams find every remaining reference to a field before it is physically removed from the schema, instead of discovering broken code paths after the column is already gone. It has no dependencies beyond Django itself and integrates purely through the model’s field declarations.

What You Get

  • A deprecate_field() wrapper that marks a Django model field as deprecated in place
  • Automatic null=True behavior during makemigrations/migrate/showmigrations so the schema stays migratable
  • A descriptor that logs a DeprecationWarning on read/write access outside migration commands
  • An optional raise_on_access mode that raises FieldDeprecatedError instead of warning
  • A return_instead option to substitute a fixed value or callable for the deprecated field’s value

Common Use Cases

  • Safely retiring a Django model field across a multi-service deployment without a hard cutover
  • Surfacing every remaining read/write of a field via logged deprecation warnings before deleting it
  • Enforcing a hard failure (raise_on_access) in staging to catch lingering references before production
  • Migrating a column to nullable ahead of a later makemigrations that drops it entirely

Under The Hood

Architecture The package is a single module, deprecate_field.py, exporting one function (deprecate_field) and one descriptor class (DeprecatedField). deprecate_field() inspects sys.argv to detect whether the current process is a migration command (makemigrations, migrate, showmigrations, or names added via DEPRECATE_FIELD_CUSTOM_MIGRATION_COMMAND); if so it returns the original field with null=True forced so migrations succeed, otherwise it wraps the field in a DeprecatedField descriptor that intercepts __get__/__set__ on the model class.

Tech Stack Pure Python with a single runtime dependency, Django>=2.1. No build step, no compiled extensions, no third-party dependencies beyond Django’s own settings and logging.

Code Quality tests/test_deprecate_field.py exercises the wrapper against a real Django test project (tests/test_project/settings.py) via Django’s own manage.py test runner, and tox.ini runs the suite across a matrix of Python/Django version combinations. The implementation is small enough (roughly 90 lines) that its behavior is easy to audit directly.

API Design The public surface is a single function call wrapped around an existing field declaration (field1 = deprecate_field(models.CharField())), which keeps the migration path to adoption trivial — no schema changes to app code are needed beyond that one line, and the return_instead/raise_on_access parameters cover the two most common deprecation policies (silent warning with a fallback value vs. hard failure) without extra configuration.

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