NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI
PyPI, #4649 most downloaded on PyPI
A reusable Django field that allows you to store validated JSON in your model.
Latest stable
3.2.0
Last release 1 years ago
04 Jul 2025
Ships unpredictably
gaps range from 1 weeks to 5.4 years
Rarely documented
notes for 1 of 35 stable releases
Nothing withdrawn
no release was ever pulled
15 years old
35 releases · first in 2012
Drag across the ruler to compare, or tap a release to open it.
Update readme with deprecation notice and migration instructions
This project publishes no release notes. Between 3.1.0 and 3.2.0 there were 9 commits, 8 of them substantive:
For now, the old fields and transforms are left as a reference to the new ones and are deprecated as of this release .
Django now supports a fully asynchronous request path, including:
Asynchronous views
Asynchronous middleware
Asynchronous tests and test client
To get started with async views, you need to declare a view using async def :
async def my_view ( request ): await asyncio . sleep ( 0.5 ) return HttpResponse ( "Hello, async world!" )
All asynchronous features are supported whether you are running under WSGI or ASGI mode. However, there will be performance penalties using async code in WSGI mode. You can read more about the specifics in Asynchronous support documentation.
You are free to mix async and sync views, middleware, and tests as much as you want. Django will ensure that you always end up with the right execution context. We expect most projects will keep the majority of their views synchronous, and only have a select few running in async mode - but it is entirely your choice.
Django’s ORM, cache layer, and other pieces of code that do long-running network calls do not yet support async access. We expect to add support for them in upcoming releases. Async views are ideal, however, if you are doing a lot of API or HTTP calls inside your view, you can now natively do all those HTTP calls in parallel to considerably speed up your view’s execution.
Asynchronous support should be entirely backwards-compatible and we have tried to ensure that it has no speed regressions for your existing, synchronous code. It should have no noticeable effect on any existing Django projects.
Django now includes models.JSONField and forms.JSONField that can be used on all supported database backends. Both fields support the use of custom JSON encoders and decoders. The model field supports the introspection, lookups, and transforms that were previously PostgreSQL-only:
from django.db import models class ContactInfo ( models . Model ): data = models . JSONField () ContactInfo . objects . create ( data = { "name" : "John" , "cities" : [ "London" , "Cambridge" ], "pets" : { "dogs" : [ "Rufus" , "Meg" ]}, } ) ContactInfo . objects . filter ( data__name = "John" , data__pets__has_key = "dogs" , data__cities__contains = "London" , ) . delete ()
If your project uses django.contrib.postgres.fields.JSONField , plus the related form field and transforms, you should adjust to use the new fields, and generate and apply a database migration. For now, the old fields and transforms are left as a reference to the new ones and are deprecated as of this release .
The new DEFAULT_HASHING_ALGORITHM transitional setting allows specifying the default hashing algorithm to use for encoding cookies, password reset tokens in the admin site, user sessions, and signatures created by django.core.signing.Signer and django.core.signing.dumps() .
Support for SHA-256 was added in Django 3.1. If you are upgrading multiple instances of the same project to Django 3.1, you should set DEFAULT_HASHING_ALGORITHM to 'sha1' during the transition, in order to allow compatibility with the older versions of Django. Note that this requires Django 3.1.1+. Once the transition to 3.1 is complete you can stop overriding DEFAULT_HASHING_ALGORITHM .
This setting is deprecated as of this release, because support for tokens, cookies, sessions, and signatures that use SHA-1 algorithm will be removed in Django 4.0.
The new django.contrib.admin.EmptyFieldListFilter for ModelAdmin.list_filter allows filtering on empty values (empty strings and nulls) in the admin changelist view.
Filters in the right sidebar of the admin changelist view now contain a link to clear all filters.
The admin now has a sidebar on larger screens for easier navigation. It is enabled by default but can be disabled by using a custom AdminSite and setting AdminSite.enable_nav_sidebar to False .
Rendering the sidebar requires access to the current request in order to set CSS and ARIA role affordances. This requires using 'django.template.context_processors.request' in the 'context_processors' option of OPTIONS .
Initially empty extra inlines can now be removed, in the same way as dynamically created ones.
XRegExp is upgraded from version 2.0.0 to 3.2.0.
jQuery is upgraded from version 3.4.1 to 3.5.1.
Select2 library is upgraded from version 4.0.7 to 4.0.13.
The default iteration count for the PBKDF2 password hasher is increased from 180,000 to 216,000.
The new PASSWORD_RESET_TIMEOUT setting allows defining the number of seconds a password reset link is valid for. This is encouraged instead of the deprecated PASSWORD_RESET_TIMEOUT_DAYS setting, which will be removed in Django 4.0.
The password reset mechanism now uses the SHA-256 hashing algorithm. Support for tokens that use the old hashing algorithm remains until Django 4.0.
AbstractBaseUser.get_session_auth_hash() now uses the SHA-256 hashing algorithm. Support for user sessions that use the old hashing algorithm remains until Django 4.0.
The new remove_stale_contenttypes --include-stale-apps option allows removing stale content types from previously installed apps that have been removed from INSTALLED_APPS .
relate lookup is now supported on MariaDB.
Added the LinearRing.is_counterclockwise property.
AsGeoJSON is now supported on Oracle.
Added the AsWKB and AsWKT functions.
Added support for PostGIS 3 and GDAL 3.
intword template filter now supports negative integers.
The new BloomIndex class allows creating bloom indexes in the database. The new BloomExtension migration operation installs the bloom extension to add support for this index.
get_FOO_display() now supports ArrayField and RangeField .
The new rangefield.lower_inc , rangefield.lower_inf , rangefield.upper_inc , and rangefield.upper_inf lookups allow querying RangeField by a bound type.
rangefield.contained_by now supports SmallAutoField , AutoField , BigAutoField , SmallIntegerField , and DecimalField .
SearchQuery now supports 'websearch' search type on PostgreSQL 11+.
SearchQuery.value now supports query expressions.
The new SearchHeadline class allows highlighting search results.
search lookup now supports query expressions.
The new cover_density parameter of SearchRank allows ranking by cover density.
The new normalization parameter of SearchRank allows rank normalization.
The new ExclusionConstraint.deferrable attribute allows creating deferrable exclusion constraints.
The SESSION_COOKIE_SAMESITE setting now allows 'None' (string) value to explicitly state that the cookie is sent with all same-site and cross-site requests.
The STATICFILES_DIRS setting now supports pathlib.Path .
The cache_control() decorator and patch_cache_control() method now support multiple field names in the no-cache directive for the Cache-Control header, according to RFC 7234 Section 5.2.2.2 .
delete() now returns True if the key was successfully deleted, False otherwise.
The CSRF_COOKIE_SAMESITE setting now allows 'None' (string) value to explicitly state that the cookie is sent with all same-site and cross-site requests.
The EMAIL_FILE_PATH setting, used by the file email backend , now supports pathlib.Path .
django.views.debug.SafeExceptionReporterFilter now filters sensitive values from request.META in exception reports.
The new SafeExceptionReporterFilter.cleansed_substitute and SafeExceptionReporterFilter.hidden_settings attributes allow customization of sensitive settings and request.META filtering in exception reports.
The technical 404 debug view now respects DEFAULT_EXCEPTION_REPORTER_FILTER when applying settings filtering.
The new DEFAULT_EXCEPTION_REPORTER allows providing a django.views.debug.ExceptionReporter subclass to customize exception report generation. See Custom error reports for details.
FileSystemStorage.save() method now supports pathlib.Path .
FileField and ImageField now accept a callable for storage . This allows you to modify the used storage at runtime, selecting different storages for different environments, for example.
ModelChoiceIterator , used by ModelChoiceField and ModelMultipleChoiceField , now uses ModelChoiceIteratorValue that can be used by widgets to access model instances. See Iterating relationship choices for details.
django.forms.DateTimeField now accepts dates in a subset of ISO 8601 datetime formats, including optional timezone, e.g. 2019-10-10T06:47 , 2019-10-10T06:47:23+04:00 , or 2019-10-10T06:47:23Z . The timezone will always be retained if provided, with timezone-aware datetimes being returned even when USE_TZ is False .
Additionally, DateTimeField now uses DATE_INPUT_FORMATS in addition to DATETIME_INPUT_FORMATS when converting a field input to a datetime value.
MultiWidget.widgets now accepts a dictionary which allows customizing subwidget name attributes.
The new BoundField.widget_type property can be used to dynamically adjust form rendering based upon the widget type.
The LANGUAGE_COOKIE_SAMESITE setting now allows 'None' (string) value to explicitly state that the cookie is sent with all same-site and cross-site requests.
Added support and translations for the Algerian Arabic, Igbo, Kyrgyz, Tajik, and Turkmen languages.
The new check --database option allows specifying database aliases for running the database system checks. Previously these checks were enabled for all configured DATABASES by passing the database tag to the command.
The new migrate --check option makes the command exit with a non-zero status when unapplied migrations are detected.
The new returncode argument for CommandError allows customizing the exit status for management commands.
The new dbshell -- ARGUMENTS option allows passing extra arguments to the command-line client for the database.
The flush and sqlflush commands now include SQL to reset sequences on SQLite.
The new ExtractIsoWeekDay function extracts ISO-8601 week days from DateField and DateTimeField , and the new iso_week_day lookup allows querying by an ISO-8601 day of week.
QuerySet.explain() now supports:
TREE format on MySQL 8.0.16+,
analyze option on MySQL 8.0.18+ and MariaDB.
Added PositiveBigIntegerField which acts much like a PositiveIntegerField except that it only allows values under a certain (database-dependent) limit. Values from 0 to 9223372036854775807 are safe in all databases supported by Django.
The new RESTRICT option for on_delete argument of ForeignKey and OneToOneField emulates the behavior of the SQL constraint ON DELETE RESTRICT .
CheckConstraint.check now supports boolean expressions.
The RelatedManager.add() , create() , and set() methods now accept callables as values in the through_defaults argument.
The new is_dst parameter of the QuerySet.datetimes() determines the treatment of nonexistent and ambiguous datetimes.
The new F expression bitxor() method allows bitwise XOR operation .
QuerySet.bulk_create() now sets the primary key on objects when using MariaDB 10.5+.
The DatabaseOperations.sql_flush() method now generates more efficient SQL on MySQL by using DELETE instead of TRUNCATE statements for tables which don’t require resetting sequences.
SQLite functions are now marked as deterministic on Python 3.8+. This allows using them in check constraints and partial indexes.
The new UniqueConstraint.deferrable attribute allows creating deferrable unique constraints.
Paginator can now be iterated over to yield its pages.
If ALLOWED_HOSTS is empty and DEBUG=True , subdomains of localhost are now allowed in the Host header, e.g. static.localhost .
HttpResponse.set_cookie() and HttpResponse.set_signed_cookie() now allow using samesite='None' (string) to explicitly state that the cookie is sent with all same-site and cross-site requests.
The new HttpRequest.accepts() method returns whether the request accepts the given MIME type according to the Accept HTTP header.
The SECURE_REFERRER_POLICY setting now defaults to 'same-origin' . With this configured, SecurityMiddleware sets the Referrer Policy header to same-origin on all responses that do not already have it. This prevents the Referer header being sent to other origins. If you need the previous behavior, explicitly set SECURE_REFERRER_POLICY to None .
The default algorithm of django.core.signing.Signer , django.core.signing.loads() , and django.core.signing.dumps() is changed to the SHA-256. Support for signatures made with the old SHA-1 algorithm remains until Django 4.0.
Also, the new algorithm parameter of the Signer allows customizing the hashing algorithm.
The renamed translate and blocktranslate template tags are introduced for internationalization in template code. The older trans and blocktrans template tags aliases continue to work, and will be retained for the foreseeable future.
The include template tag now accepts iterables of template names.
SimpleTestCase now implements the debug() method to allow running a test without collecting the result and catching exceptions. This can be used to support running tests under a debugger.
The new MIGRATE test database setting allows disabling of migrations during a test database creation.
DiscoverRunner can now discard output for passing tests using the test --buffer option.
DiscoverRunner now skips running the system checks on databases not referenced by tests .
TransactionTestCase teardown is now faster on MySQL due to flush command improvements. As a side effect the latter doesn’t automatically reset sequences on teardown anymore. Enable TransactionTestCase.reset_sequences if your tests require this feature.
Path converters can now raise ValueError in to_url() to indicate no match when reversing URLs.
filepath_to_uri() now supports pathlib.Path .
parse_duration() now supports comma separators for decimal fractions in the ISO 8601 format.
parse_datetime() , parse_duration() , and parse_time() now support comma separators for milliseconds.
The SQLite backend now supports pathlib.Path for the NAME setting.
The settings.py generated by the startproject command now uses pathlib.Path instead of os.path for building filesystem paths.
The TIME_ZONE setting is now allowed on databases that support time zones.
Your coding agent can read these notes before it upgrades. Set up the MCP server →
This project publishes no release notes. Between 3.0.0 and 3.1.0 there were 24 commits, 22 of them substantive:
…and 2 more.
This project publishes no release notes. Between 2.1.1 and 3.0.0 there were 76 commits, 65 of them substantive:
This project publishes no release notes. Between 2.1.1 and 3.0.0 there were 76 commits, 65 of them substantive:
…and 45 more.
This project publishes no release notes. Between 2.1.0 and 2.1.1 there were 5 commits, 2 of them substantive:
This project publishes no release notes. Between 2.1.0 and 2.1.1 there were 5 commits, 2 of them substantive:
Eliminate Django 2.0 deprecation warning
This project publishes no release notes. Between 2.0.2 and 2.1.0 there were 17 commits, 11 of them substantive:
This project publishes no release notes. Between 2.0.1 and 2.0.2 there were 12 commits, 7 of them substantive:
This project publishes no release notes. Between 2.0.1 and 2.0.2 there were 12 commits, 7 of them substantive:
This project publishes no release notes. Between 2.0.0 and 2.0.1 there were 8 commits, 4 of them substantive:
This project publishes no release notes. Between 2.0.0 and 2.0.1 there were 8 commits, 4 of them substantive:
This project publishes no release notes. Between 1.0.3 and 2.0.0 there were 31 commits, 21 of them substantive:
This project publishes no release notes. Between 1.0.3 and 2.0.0 there were 31 commits, 21 of them substantive:
README.rst with svg bagde…and 1 more.
This project publishes no release notes. Between 1.0.2 and 1.0.3 there were 9 commits, 6 of them substantive:
This project publishes no release notes. Between 1.0.2 and 1.0.3 there were 9 commits, 6 of them substantive:
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
One column per quarter.