Upgrading
This page collects the breaking changes and upgrade steps for major version bumps of Django OAuth Toolkit, so you don’t have to reconstruct them from the Changelog. The changelog remains the authoritative, complete record — always read the entries between your current version and your target version before upgrading. This page summarizes the changes most likely to break a running deployment.
General upgrade procedure
Read the changelog for every release between your current and target version, not only the target — breaking changes are sometimes introduced in a major release and then have follow-ups in later ones.
Pin the exact version you are upgrading to and test in a staging environment before production.
Run migrations. After upgrading the package, run
python manage.py migrate. Major releases frequently ship model changes.Regenerate migrations for swapped models. If you have swapped any of the toolkit’s models (application or token models), run
python manage.py makemigrationsfor your app and thenmigrate, so your custom models pick up the same schema changes.Check for removed deprecations. Major releases remove things that earlier releases warned about with a
DeprecationWarning. Run your test suite with warnings enabled (python -W all) on the previous version first to surface anything you still rely on.
Upgrading to 2.0
2.0.0 is a major release with breaking changes. The two most likely to surface in a running
deployment are the client-secret hashing change — which shows up as an {"error":
"invalid_client"} response at the token endpoint — and PKCE now being required, which instead
fails with an invalid_request / invalid_grant error for clients that don’t send a PKCE
challenge.
Client secrets are now hashed on save (#1093). Existing cleartext
application.client_secretvalues are migrated to Django password-style hashes on upgrade, and the hashing cannot be reversed. When you create or edit an application (in the admin or via the API), copy the generated/entered secret before saving — afterwards only the hash is stored. Clients configured with the old cleartext value keep working; only reading back a secret is no longer possible. If you have automation that readsclient_secretout of the database, it must be updated.PKCE is now required by default (#1129).
PKCE_REQUIREDdefaults toTrue, so authorization-code clients that do not send a PKCEcode_challenge/code_verifierwill fail. Either add PKCE to those clients (recommended) or setPKCE_REQUIREDtoFalseto retain the pre-2.x behavior. Note that it is namespaced under theOAUTH2_PROVIDERsetting, not a top-level Django setting:OAUTH2_PROVIDER = { # ... "PKCE_REQUIRED": False, }
OIDC standard scopes now gate claims (#1108). Default OIDC scopes now determine which claims are returned. If you customized OIDC responses and want the pre-2.x behavior, set
oidc_claim_scope = Nonein yourOAuth2Validatorsubclass.The ``oob`` redirect URIs were removed (#1124). Support for the insecure
urn:ietf:wg:oauth:2.0:oobandurn:ietf:wg:oauth:2.0:oob:autoredirect URIs is gone, replaced by RFC 8252 “OAuth 2.0 for Native Apps”. If you still rely onoob, migrate those native clients to a loopback or custom-scheme redirect before upgrading.
Upgrading to 3.0
3.0.0 requires a schema migration and drops support for older Django versions.
Run ``migrate`` — the ``AccessToken`` model changed (#1447). The
tokencolumn became aTextField(removing the 255-character limit so JWT access tokens with extra claims fit), and a newtoken_checksum(SHA-256) field is used to look tokens up. Runpython manage.py migrateafter upgrading; if you use swapped models, runmakemigrationsfor your app first.Warning
Swapped access token models need a manual ``token_checksum`` backfill. The built-in migration backfills
token_checksumfor the defaultAccessTokenonly — it deliberately skips a swapped access token model (and logs a warning to that effect). Until you backfill the checksum for your existing rows, those access tokens will fail validation. Backfill it in a data migration on your app, computinghashlib.sha256(token.encode("utf-8")).hexdigest()for each existing row (mirroring whatoauth2_provider’s0012_add_token_checksummigration does for the default model).Models now use ``pk`` instead of ``id`` (#1446). This lets swapped models use a different primary-key field. If any of your code assumed an
idattribute on the toolkit’s models, usepkinstead.Django < 4.2 is no longer supported (#1455). Upgrade Django to 4.2 or newer first.
Deprecations from 2.4.0 were removed (#1425).
RedirectURIValidatorandWildcardSet(deprecated in #1345) are gone — replace any imports of them. The deprecated importablevalidate_logout_requesthelper was also removed (#1274); note that this is distinct from theRPInitiatedLogoutView.validate_logout_requestmethod, which still exists — so if you grep the codebase and still findvalidate_logout_request, that method is expected to be there.Token cleanup writes now honor database routers (#1450). If you run a multi-database setup, ensure your routers direct the token models to the correct database (see the multiple-databases note).
Note
For the full, authoritative list of changes in every release — including minor and patch releases not covered here — see the Changelog.