Changelog¶
1.31.1 (2026-06-26)¶
Remove the
settings_logging_admin_email_handlerfixer because it made an incorrect change and cannot be salvaged.Thanks to Mike Edmunds for spotting the mistake in this GitHub comment. PR #671.
1.31.0 (2026-06-25)¶
Support Django 6.1 as a target version.
Add Django 6.1+ mail_get_connection fixer to replace no-argument mail
get_connection()calls withmailers.default, and remove inlineconnection=get_connection()kwargs from mail sending functions.Add Django 6.1+ mail_fail_silently fixer to remove
fail_silently=Falsekeyword arguments from mail sending function calls.Add Django 6.1+
settings_logging_admin_email_handlerfixer to rename theemail_backendargument ofAdminEmailHandlerin theLOGGINGsetting tousing.Add Django 6.1+
compatibility_importsfixer entries to moveBitAnd,BitOr, andBitXorimports fromdjango.contrib.postgres.aggregatestodjango.db.models.Add Django 6.1+ transaction_savepoint fixer to rename
django.db.transaction’ssavepointtosavepoint_create.Add Django 2.0+ render_to_response fixer to rewrite
render_to_response()calls torender(), insertingrequestas the first argument.Extend test_http_headers fixer to cover
AsyncClient,AsyncRequestFactory, andself.async_client.*()calls.Thanks to Benjamin Aduo in PR #633.
Extend django_urls fixer to convert translated URL patterns wrapped in translation functions, like
_(r'^about/$'), when the pattern is convertible.Extend django.utils.timezone.utc deprecations fixer to work when no
import datetimestatement exists, by insertingimport datetime as dtwhen the namedtis unused.Thanks to Ryan Siemens for the report in Issue #568 and Benjamin Aduo for the implementation in PR #631.
Extend versioned_test_skip_decorators fixer to also remove the entire decorated function or class when the skip condition is always true. For example, when targeting Django 5.2+, a function decorated with
@pytest.mark.skipif(django.VERSION >= (5, 2), ...)will be removed.Extend versioned_test_skip_decorators fixer to support async function definitions.
Add Django 1.11+ fixer permalink to rewrite
@models.permalinkdecorator usages to usereverse()directly.PR #647. Thanks to Joerg Sonnenberger for the report in Issue #645 and review.
Fix null_boolean_field fixer when
NullBooleanFieldis used in non-call contexts, for example as a base class.Fix versioned_branches fixer to avoid leaving code with broken syntax emptying a parent block. A
passis now inserted to keep the code valid.Fix these fixers to correctly handle calls with starred arguments:
For example, the signal_providing_args fixer now rewrites
Signal(providing_args=[...], *args)toSignal(*args).
1.30.0 (2026-02-24)¶
Support parsing Django versions without a minor part from
pyproject.toml. For example,django>=6will be parsed as for Django 6.0+.Drop Python 3.9 support.
1.29.1 (2025-10-23)¶
Remove the
AppConfigrewriting behaviour of default_auto_field. It was unsafe for projects settingDEFAULT_AUTO_FIELDto a field other thanBigAutoField, triggering regressive migrations for primary keys in affected apps.
1.29.0 (2025-10-06)¶
Add Django 6.0+ fixer mail_api_kwargs to rewrite positional arguments to keyword arguments for some
django.core.mailAPIs.Add Django 6.0+ fixer default_auto_field to remove now-redundant auto field specifications. The fixer removes the
DEFAULT_AUTO_FIELDsetting andAppConfig.default_auto_fieldattribute when they are set to the new default ofdjango.db.models.BigAutoField.Thanks to q0w in PR #591.
Add Django 6.0+ fixer stringagg to rewrite
StringAggimports fromdjango.contrib.postgres.aggregatestodjango.db.models. This fixer replaces the compatibility import rewrite added in 1.27.0, and now correctly wraps thedelimiterargument inValue()when it is a string literal.Add Django 6.0+ fixer settings_admins_managers to rewrite the
ADMINSandMANAGERSsettings to drop the previously-unused name parts of the tuples.
1.28.0 (2025-09-09)¶
Support Python 3.14.
1.27.0 (2025-08-27)¶
Support Django 6.0 as a target version.
Add Django 6.0+ fixer settings_forms_urlfield_assume_https to remove the transitional setting
FORMS_URLFIELD_ASSUME_HTTPS.Add Django 6.0+ compatibility import rewrite of
StringAggfromdjango.contrib.postgres.aggregatestodjango.db.models.Improve the django_urls fixer slightly:
Regular expression URLs with a
.are now converted topath()syntax.Thanks to Iteron-dev for the report in Issue #567.
Invalid group names are no longer converted to
path()syntax.
1.26.0 (2025-08-26)¶
Add
--checkoption that only reports which files would be changed.Thanks to berzi in PR #581.
Improve stdin handling: exit with code 0 even when changes were made for stdin, and print all other output to stderr.
Fix the
request_headersfixer for non-stringincomparisons like1 in request.META(unlikely in real code).
1.25.0 (2025-05-13)¶
Add support for class-based settings files in the
use_l10nfixer.
1.24.0 (2025-03-27)¶
Parse target Django version from
pyproject.toml. Now, if you don’t specify a version with--target-version, django-upgrade will try to parse your minimum-supported target Django version fromproject.dependenciesinpyproject.toml. It supports several common formats, likedjango>=5.2,<6.0.Add Django 5.2+ fixer postgres_aggregate_order_by to rewrite PostgreSQL aggregate functions using the old argument name
orderingto the new nameorder_by.Add Django 5.2+ fixer staticfiles_find_all to rewrite calls to the staticfiles
find()function using the old argument nameallto the new namefind_all.Restore Django 5.0+ fixer model_field_choices, with a restriction to only apply when the enumeration type is defined in the same file.
Thanks to Thibaut Decombe for initially contributing it in PR #369.
Add Django 2.0+ compatibility import rewrite of django.http.cookie.SimpleCookie to http.cookies.SimpleCookie.
Thanks to Thibaut Decombe in PR #537.
1.23.1 (2025-02-07)¶
Fix django_urls fixer bug that failed for indented path strings. This bug was introduced in 1.23.0.
Thanks to Michal Čihař for the report in Issue #528.
1.23.0 (2025-02-06)¶
Support Django 5.2 in
--target-version.Extend versioned block fixer to support comparisons with single-item tuples, like django.VERSION >= (4,).
Thanks to Thibaut Decombe in PR #517.
Fix versioned_test_skip_decorators fixer to remove all indentation tokens from the decorator line.
Thanks to Thibaut Decombe in PR #518.
Fix django_urls fixer handling of implicitly concatenated strings.
Thanks to Gunther Waidacher for the report in Issue #524.
1.22.2 (2024-12-02)¶
Make these fixers work when
django.contrib.gis.db.modelsis used to import objects fromdjango.db.models:
1.22.1 (2024-10-11)¶
Fix circular import error when running django-upgrade.
Thanks to Michal Čihař for the report in Issue #503.
1.22.0 (2024-10-10)¶
Avoid accidental removal of comments a removed
ifblock in the versioned block fixer.Thanks to Tobias Funke for the report in Issue #495.
Add all-version fixer to remove outdated test skip decorators.
Drop Python 3.8 support.
Support Python 3.13.
1.21.0 (2024-09-05)¶
Add Django 5.0+ fixer to rewrite
format_html()calls withoutargsorkwargsprobably usingstr.format()incorrectly.
1.20.0 (2024-07-19)¶
Fix the
admin_registerfixer to avoid rewriting when there are duplicateModelAdminclasses in the file.
1.19.0 (2024-06-27)¶
Add Django 4.2+ fixer to rewrite
index_togetherdeclarations intoindexesdeclarations in modelMetaclasses. This fixer can make changes that require migrations. Add a test for pending migrations to ensure that you do not miss these.Fix tracking of AST node parents. This may have fixed some subtle bugs in these fixers:
admin_registerassert_form_errordefault_app_configmanagement_commandsrequest_headerssettings_database_postgresqlsettings_storagestestcase_databasesuse_l10nutils_timezone
If you see any new changes, or had them previously disabled, please report an issue so we can extra tests to the test suite.
1.18.0 (2024-05-28)¶
Support Django 5.1 as a target version.
Add Django 5.1+ fixer to rewrite the
checkkeyword argument ofCheckConstrainttocondition.
1.17.0 (2024-05-10)¶
Add fixer selection options:
--only <name>,--skip <name>, and--list-fixers.Thanks to Gav O’Connor and David Szotten in PR #443.
Run per-file conditions once, yielding a performance improvement of ~2% measured on a real-world project.
1.16.0 (2024-02-11)¶
Remove the Django 5.0+ fixer that dropped
.choicesfrom model fieldchoicesparameters. It was too unreliable because it could break use for “DIY” enumeration types.Thanks to Niccolò Mineo and washeck for reporting in Issue #417.
Add Django 1.10+ fixer to rewrite
request.userfunctions that changed to boolean attributes:is_authenticatedandis_anonymous.Thanks to Alessandro Ferrini in PR #423.
Add Django 2.0+ imports fixes for names moved from
django.core.urlresolverstodjango.urls.Thanks to Thibaut Decombe in PR #404.
1.15.0 (2023-09-24)¶
Support Django 5.0 as a target version.
Add Django 5.0+ fixer to drop
.choiceson model fieldchoicesparameters when using an enumeration type.Thanks to Thibaut Decombe in PR #369.
Add some compatibility import replacements for Django 4.0 and below.
Thanks to Thibaut Decombe in PR #368.
Fix issue with
@admin.register()checkerThanks to Jan Pieter Waagmeester for the report in Issue #337, and to Thibaut Decombe for the review in PR #338.
1.14.1 (2023-08-16)¶
Fix bug in
STORAGESfixer when only one ofDEFAULT_FILE_STORAGEorSTATICFILES_STORAGEwas defined.Thanks to Bruno Alla in PR #376.
1.14.0 (2023-06-14)¶
Support Python 3.12.
1.13.0 (2023-02-17)¶
Add Django 4.2+ fixer to combine deprecated
DEFAULT_FILE_STORAGEandSTATICFILES_STORAGEsettings into the newSTORAGESsetting.Add Django 4.2+ fixer to rewrite HTTP headers passed to test
ClientandRequestFactory.Thanks to David Wobrock in PR #305.
Add Django 4.2+ fixer to rewrite test case methods
assertFormsetError()andassertQuerysetEqual()into the new spellings with capitalized “Set”.Thanks to Michael Howitz in PR #253.
Add Django 4.0 fixer to rewrite
django.contrib.admin.utils.lookup_needs_distinct->lookup_spawns_duplicates.Thanks to Bruno Alla in PR #313.
Rewrite
request.META->request.headerson the right hand side of assignments.Group some compatibility import replacements into a single “fixer”, optimizing runtime by about 3%.
Thanks to Thibaut Decombe in PR #295.
1.12.0 (2022-11-09)¶
Make
re_path->pathfixer also convertinclude()'s with unterminated regexes.Thanks to Thibaut Decombe in PR #279.
Avoid rewriting
request.METAtorequest.headersindelstatements. This pattern works forrequest.METAbut not forrequest.headerswhich is an immutable mapping.Thanks to Thibaut Decombe in PR #290.
Add Django 1.9+ fixer to rename the legacy engine name
django.db.backends.postgresql_psycopg2insettings.DATABASEStodjango.db.backends.postgresql.Thanks to Thibaut Decombe in PR #280.
Make detection of management commands and migration files detect both forward and backward slashes as directory separators.
Thanks to William Claassen in PR #286.
1.11.0 (2022-10-26)¶
See also the release blog post.
Add Django 1.7+ fixer to rewrite
admin.site.register()calls into@admin.register()when eligible.Thanks to Thibaut Decombe in PR #189.
Add Django 3.2+ fixer to rewrite admin action function attributes to use the
@admin.action()decorator.Add Django 3.2+ fixer to rewrite admin display function attributes to use the
@admin.display()decorator.Add Django 4.1+ fixer to rewrite calls to test case methods
assertFormError()andassertFormsetError()from their old signatures to the new ones.Add Django 2.0+ fixer to drop assignments of
allow_tagsattributes toTrue.Add Django 3.1+ fixer to replace
listerror message key withlist_invalidonModelMultipleChoiceField.Thanks to Thibaut Decombe in PR #258.
Make
request.headersfixer also rewrite accesses of thecontent-lengthandcontent-typeheaders.Thanks to Christian Bundy in PR #226.
Extend
request.headersfixer to rewriteinandnot incomparisons onrequest.META.Thanks to Daan Vielen in Issue #234.
The
request.headersfixer now uses lowercase for header lookups, as per the HTTP/2 specification.Make
on_deletefixer also supportForeignKeyandOneToOneFieldimported fromdjango.db.models.Thanks to Thibaut Decombe in PR #236.
Make
NullBooleanFieldfixer preserve existingnullarguments.Thanks to Joseph Zammit in Issue #245.
Update
timezone.utcfixer to only use absolute references from existing imports of thedatetimemodule.Make Django 2.0+ URL fixer avoid a loop of adding imports that already exist.
Thanks to Benjamin Bach for the report in Issue #250, and to Thibaut Decombe for the fix in PR #270.
Fixers that modify string literals now match existing use of double quotes.
Thanks to Kevin Marsh in PR #260.
Make fixers that erase lines also erase any trailing comments.
Fix leaving a trailing comma when editing imports in certain cases.
Expand the range of files considered settings files.
Require at least one filename.
Thanks to Daan Vielen in Issue #238.
Update README with info on how to run an upgrade on entire project.
Thanks to Daan Vielen in Issue #240.
1.10.0 (2022-09-07)¶
Add Django 3.2+ fixer to update
requires_system_checksin management command classes.Thanks to Bruno Alla in PR #184.
1.9.0 (2022-08-25)¶
Add Django 4.0+ fixer to remove
USE_L10N = Truesetting.Thanks to Johnny Metz in PR #173.
Add fixer to remove outdated blocks based on comparing
django.VERSIONto old versions:-if django.VERSION > (4, 1): - constraint.validate() +constraint.validate()
Update Django 2.0+ URL fixer to rewrite
re_path()calls intopath()when eligible.Thanks to Thibaut Decombe in PR #167.
1.8.1 (2022-08-25)¶
Fix
timezone.utcfixer to import and usetimezone.utccorrectly.Thanks to Víðir Valberg Guðmundsson for the report in Issue #172.
1.8.0 (2022-08-11)¶
Support Django 4.1 as a target version.
Add Django 4.1+ fixer to rewrite imports of
utcfromdjango.utils.timezoneto usedatetime.timezone.Thanks to Hasan Ramezani in PR #169.
1.7.0 (2022-05-11)¶
Support Python 3.11.
1.6.1 (2022-05-04)¶
1.6.0 (2022-05-04)¶
Add Django 3.2+ fixer to remove
default_app_configassignments in__init__.pyfiles.Thanks to Bruno Alla in PR #140.
1.5.0 (2022-04-14)¶
Fix URL rewriting to avoid converting regular expressions that don’t end with
$. If the$is missing, Django will search for the given regular expression anywhere in the path.Thanks to qdufrois for the report in Issue #121.
Made
JSONFieldandNullBooleanFieldfixers ignore migrations files. Django kept these old field classes around for use in historical migrations, so there’s no need to rewrite such cases.Thanks to Matthieu Rigal and Bruno Alla for the report in Issue #79.
1.4.0 (2021-10-23)¶
Add Django 2.0+ fixer to rewrite imports of
lru_cachefromdjango.utils.functionalto usefunctools.Support Django 4.0 as a target version. There are no fixers for it at current. Most of its deprecations don’t seem automatically fixable.
1.3.2 (2021-09-23)¶
Avoid rewriting
request.METAtorequest.headersin assignments. This pattern is used in tests, and works forrequest.METAbut notrequest.headers.Thanks to Bruno Alla for the report in Issue #74.
1.3.1 (2021-09-22)¶
Fix import fixers to not crash on star imports (
from foo import *).Thanks to Mikhail for the report in Issue #70.
1.3.0 (2021-09-22)¶
Fix
get_random_string()fixer to not add the argument to calls likecrypto.get_random_string(12).Add fixers to remove various compatibility imports removed in Django 3.1.
Thanks to Bruno Alla in PR #44.
Add fixer for Django 2.2 to rewrite
request.METAaccess of headers toHttpRequest.headers.Add fixer for Django 2.0 to rewrite
include()andurl()fromdjango.conf.urlstodjango.urls.url()may be rewritten topath()orre_path()accordingly.Thanks to Bruno Alla for the original implementation of regex-to-path conversion in django-codemod. Thanks to Matthias Kestenholz for an initial PR.
Add fixer for Django 1.9 requirement to pass
on_deletetoForeignKeyandOneToOneField.Thanks to Bruno Alla in PR #61.
1.2.0 (2021-09-02)¶
Support Python 3.10.
Support single level module imports of names too, such as using o
from django.utils import cryptowithcrypto.get_random_string().Add fixer for Django 3.1 deprecation of
NullBooleanField.Add fixers for Django 3.0 deprecation of functions in
django.utils.http,django.utils.text, anddjango.utils.translation.Add fixer for Django 2.2 rename of
FloatRangeFieldtoDecimalRangeField.Add fixer for Django 2.2 deprecation of test case attributes
allow_database_queriesandmulti_db.Fix inserted imports to match indentation of the point they are inserted.
1.1.0 (2021-08-28)¶
Add fixer for Django 3.1
JSONFieldmoves.Add fixer for Django 3.1 removal of
Signal’s argumentproviding_args.Add fixer for Django 3.1 requirement to pass
get_random_string()thelengthargument.Fix Python 3.8 compatibility.
Drop Python 3.6 and 3.7 support, since they never worked, and the incompatibilities in the
astmodule are hard to cover.
1.0.0 (2021-08-27)¶
Initial release.