Skip to main content

Automatically upgrade your Django projects.

Project description

https://img.shields.io/github/workflow/status/adamchainz/django-upgrade/CI/main?style=for-the-badge https://img.shields.io/codecov/c/github/adamchainz/django-upgrade/main?style=for-the-badge https://img.shields.io/pypi/v/django-upgrade.svg?style=for-the-badge https://img.shields.io/badge/code%20style-black-000000.svg?style=for-the-badge pre-commit

Automatically upgrade your Django projects.

Installation

Use pip:

python -m pip install django-upgrade

Python 3.8 to 3.9 supported.

Or with pre-commit in the repos section of your .pre-commit-config.yaml file (docs):

-   repo: https://github.com/adamchainz/django-upgrade
    rev: ''  # replace with latest tag on GitHub
    hooks:
    -   id: django-upgrade
        args: [--target-version, "3.2"]   # Replace with Django version

Works best before any reformatters such as isort or Black.


Are your tests slow? Check out my book Speed Up Your Django Tests which covers loads of best practices so you can write faster, more accurate tests.


Usage

django-upgrade is a commandline tool that rewrites files in place. Pass your Django version as <major>.<minor> with --target-version and the fixers will rewrite code not to trigger DeprecationWarning on that version of Django. For example:

django-upgrade --target-version 3.2 example/core/models.py example/settings.py

For more on usage run django-upgrade --help. The full list of fixers is below.

History

django-codemod is a pre-existing, more complete Django auto-upgrade tool, written by Bruno Alla. Unfortunately its underlying library LibCST is particularly slow, making it annoying to run django-codemod on every commit and in CI. Additionally LibCST only advertises support up to Python 3.8 (at time of writing).

django-upgrade is an experiment in reimplementing such a tool using the same techniques as the fantastic pyupgrade. The tool leans on the standard library’s ast and tokenize modules, the latter via the tokenize-rt wrapper. This means it will always be fast and support the latest versions of Python.

For a quick benchmark: running django-codemod against a medium Django repository with 153k lines of Python takes 133 seconds. pyupgrade and django-upgrade both take less than 0.5 seconds.

Fixers

Django 2.2

Based on the Django 2.2 release notes.

QuerySetPaginator

Rewrites depreceated alias django.core.paginator.QuerySetPaginator to Paginator.

-from django.core.paginator import QuerySetPaginator
+from django.core.paginator import Paginator

-QuerySetPaginator(...)
+Paginator(...)

FixedOffset

Rewrites deprecated class FixedOffset(x, y)) to timezone(timedelta(minutes=x), y)

Known limitation: this fixer will leave code broken with an ImportError if FixedOffset is called with only *args or **kwargs.

-from django.utils.timezone import FixedOffset
-FixedOffset(120, "Super time")
+from datetime import timedelta, timezone
+timezone(timedelta(minutes=120), "Super time")

Django 3.0

Based on the Django 3.0 release notes.

django.utils.encoding aliases

Rewrites smart_text() to smart_str(), and force_text() to force_str().

-from django.utils.encoding import force_text, smart_text
+from django.utils.encoding import force_str, smart_str


-force_text("yada")
-smart_text("yada")
+force_str("yada")
+smart_str("yada")

Django 3.1

Based on the Django 3.1 release notes.

JSONField

Rewrites imports of JSONField and related transform classes from those in django.contrib.postgres to the new all-database versions.

-from django.contrib.postgres.fields import JSONField
+from django.db.models import JSONField

PASSWORD_RESET_TIMEOUT_DAYS

Rewrites the setting PASSWORD_RESET_TIMEOUT_DAYS to PASSWORD_RESET_TIMEOUT, adding the multiplication by the number of seconds in a day.

Settings files are heuristically detected as modules with the whole word “settings” somewhere in their path. For example myproject/settings.py or myproject/settings/production.py.

-PASSWORD_RESET_TIMEOUT_DAYS = 4
+PASSWORD_RESET_TIMEOUT = 60 * 60 * 24 * 4

Signal

Removes the deprecated documentation-only providing_args argument.

 from django.dispatch import Signal
-my_cool_signal = Signal(providing_args=["documented", "arg"])
+my_cool_signal = Signal()

get_random_string

Injects the now-required length argument, with its previous default 12.

 from django.utils.crypto import get_random_string
-key = get_random_string(allowed_chars="01234567899abcdef")
+key = get_random_string(length=12, allowed_chars="01234567899abcdef")

Django 3.2

Based on the Django 3.2 release notes.

EmailValidator

Rewrites keyword arguments to their new names: whitelist to allowlist, and domain_whitelist to domain_allowlist.

 from django.core.validators import EmailValidator

-EmailValidator(whitelist=["example.com"])
+EmailValidator(allowlist=["example.com"])
-EmailValidator(domain_whitelist=["example.org"])
+EmailValidator(domain_allowlist=["example.org"])

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-upgrade-1.1.0.tar.gz (15.4 kB view details)

Uploaded Source

Built Distribution

django_upgrade-1.1.0-py3-none-any.whl (17.9 kB view details)

Uploaded Python 3

File details

Details for the file django-upgrade-1.1.0.tar.gz.

File metadata

  • Download URL: django-upgrade-1.1.0.tar.gz
  • Upload date:
  • Size: 15.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.6.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.2 CPython/3.9.6

File hashes

Hashes for django-upgrade-1.1.0.tar.gz
Algorithm Hash digest
SHA256 c54fb896454d9ff9bb54c3ce1a3659a83a77945197f60b96c397f16e518afbc8
MD5 b574a501d001a81c22031c934bfa76f8
BLAKE2b-256 da665a33f4262dc695f8db9ee24a47b74724da5ff3e4e902bd166f25a611cade

See more details on using hashes here.

File details

Details for the file django_upgrade-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: django_upgrade-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 17.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.6.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.2 CPython/3.9.6

File hashes

Hashes for django_upgrade-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 88a0e870c824db630732a958da0ec6c3e2bc64e2403b8ab6dfc4c789edc341f3
MD5 e03b54b8253db936444fbb9e247381a2
BLAKE2b-256 2f7af195ba03bb7c8cae26df566b3d80cdf8420966bb12ccbe199e81542d733f

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page