April 1, 2019
Welcome to Django 2.2!
These release notes cover the new features, as well as some backwards incompatible changes you'll want to be aware of when upgrading from Django 2.1 or earlier. We've begun the deprecation process for some features.
既存のプロジェクトをアップデートするときは、 How to upgrade Django to a newer version ガイドに従ってください。
Django 2.2 is designated as a long-term support release. It will receive security updates for at least three years after its release. Support for the previous LTS, Django 1.11, will end in April 2020.
Django 2.2 supports Python 3.5, 3.6, 3.7, 3.8 (as of 2.2.8), and 3.9 (as of 2.2.17). We highly recommend and only officially support the latest release of each series.
HttpRequestis now passed as the first positional argument to
RemoteUserBackend.configure_user(), if it accepts it.
StringAggdetermines the ordering of the aggregated elements.
SpGistIndexclasses allow creating
SP-GiSTindexes in the database.
BrinIndexnow has the
SearchQueryallows searching for a phrase or raw expression.
collectstatic --ignoreoption so that patterns like
/vendor/*.jscan be used.
--force-coloroption forces colorization of the command output.
inspectdbnow creates models for foreign tables on PostgreSQL.
inspectdb --include-viewsnow creates models for materialized views on Oracle and PostgreSQL.
inspectdb --include-partitionsoption allows creating models for partition tables on PostgreSQL. In older versions, models are created child tables instead the parent.
DurationFieldfor Oracle and PostgreSQL, and
dbshellis wrapped with
rlwrap, if available.
rlwrapprovides a command history and editing of keyboard input.
makemigrations --no-headeroption avoids writing header comments in generated migration file(s). This option is also available for
runservercan now use Watchman to improve the performance of watching a large number of files for changes.
Reversedatabase functions, as well as many math database functions.
Truetells the database to ignore failure to insert rows that fail uniqueness constraints or other checks.
ExtractIsoYearfunction extracts ISO-8601 week-numbering years from
DateTimeField, and the new
iso_yearlookup allows querying by an ISO-8601 week-numbering year.
QuerySet.bulk_update()method allows efficiently updating specific fields on multiple model instances.
Model.delete(). This improves the performance of autocommit by reducing the number of database round trips.
DISTINCTaggregation is added to the
allow_distinct = Trueas a class attribute on
Aggregatesubclasses allows a
distinctkeyword argument to be specified on initialization to ensure that the aggregate function is only called for each distinct value of
update_or_create()methods are now allowed on many-to-many relationships with intermediate models. The new
through_defaultsargument is used to specify values for new intermediate model instance(s).
SimpleTestCase.assertURLEqual()assertion checks for a given URL, ignoring the ordering of the query string.
assertRedirects()uses the new assertion.
Clientnow supports automatic JSON serialization of list and tuple
ORACLE_MANAGED_FILEStest database setting allows using Oracle Managed Files (OMF) tablespaces.
TestCasetest on SQLite 3.20+, just like on other backends that support deferrable constraints. These checks aren't implemented for older versions of SQLite because they would require expensive table introspection there.
DiscoverRunnernow skips the setup of databases not referenced by tests.
This section describes changes that may be needed in third-party database backends.
DatabaseFeatures.uses_savepointsnow defaults to
column_name_converter()are removed. Third party database backends may need to instead implement
DatabaseIntrospection.identifier_converter(). In that case, the constraint names that
DatabaseIntrospection.get_constraints()returns must be normalized by
SchemaEditormethods are added:
_delete_index_sql()(to pair with
_delete_unique_sql(to pair with
_delete_fk_sql()(to pair with
allow_thread_sharing, is removed.
For example, in older versions of Django:
from django.contrib import admin class BaseAdmin(admin.ModelAdmin): actions = ['a'] class SubAdmin(BaseAdmin): actions = ['b']
SubAdmin would have actions
actions follows standard Python inheritance. To get the same result as
class SubAdmin(BaseAdmin): actions = BaseAdmin.actions + ['b']
TransactionTestCaseserialized data loading¶
Initial data migrations are now loaded in
TransactionTestCase at the end of the test, after the
database flush. In older versions, this data was loaded at the beginning of the
test, but this prevents the
test --keepdb option from working
properly (the database was empty at the end of the whole test suite). This
change shouldn't have an impact on your tests unless you've customized
sqlparseis required dependency¶
To simplify a few parts of Django's database handling, sqlparse 0.2.2+ is now a required dependency. It's automatically installed along with Django.
In usage like:
from django.utils.functional import cached_property class A: @cached_property def base(self): return ... alias = base
alias is not cached. Where the problem can be detected (Python 3.6 and
later), such usage now raises
TypeError: Cannot assign the same
cached_property to two different names ('base' and 'alias').
Use this instead:
import operator class A: ... alias = property(operator.attrgetter('base'))
Permissions for proxy models are now
created using the content type of the proxy model rather than the content type
of the concrete model. A migration will update existing permissions when you
In the admin, the change is transparent for proxy models having the same
app_label as their concrete model. However, in older versions, users with
permissions for a proxy model with a different
app_label than its
concrete model couldn't access the model in the admin. That's now fixed, but
you might want to audit the permissions assignments for such proxy models
[add|view|change|delete]_myproxy) prior to upgrading to ensure the new
access is appropriate.
Finally, proxy model permission strings must be updated to use their own
app_label. For example, for
app.MyProxyModel inheriting from
Media assets are now merged using a topological sort algorithm, as the
old pairwise merging algorithm is insufficient for some cases. CSS and
incorrectly (where the old algorithm produced results correctly by
Media classes for any missing dependencies. For example,
widgets depending on
django.jQuery must specify
js=['admin/js/jquery.init.js', ...] when declaring form media assets.
To improve readability, the
UUIDField form field now displays values with
550e8400-e29b-41d4-a716-446655440000 instead of
include a check constraint to prevent negative values in the database. If you
have existing invalid data and run a migration that recreates a table, you'll
CHECK constraint failed.
For consistency with WSGI servers, the test client now sets the
Content-Length header to a string rather than an integer.
The return value of
django.utils.text.slugify() is no longer marked as
The default truncation character used by the
truncatewords_html template filters
is now the real ellipsis character (
…) instead of 3 dots. You may have to
adapt some test output comparisons.
Support for bytestring paths in the template filesystem loader is removed.
cx_Oracle < 6.0 is removed.
The minimum supported version of
mysqlclient is increased from 1.3.7 to
The minimum supported version of SQLite is increased from 3.7.15 to 3.8.3.
In an attempt to provide more semantic query data,
<option> values of
3. For backwards compatibility, the old values are
still accepted as data.
is increased from 80 to 150 characters.
Tests that violate deferrable database constraints now error when run on SQLite 3.20+, just like on other backends that support such constraints.
To catch usage mistakes, the test
django.utils.http.urlencode() now raise
passed as a value to encode because
None can't be encoded in GET and POST
data. Either pass an empty string or omit the value.
ping_google management command now defaults to
http for the sitemap's URL. If your site uses http, use the
ping_google --sitemap-uses-http option. If you use the
ping_google() function, set the new
sitemap_uses_https argument to
runserver no longer supports
pyinotify (replaced by Watchman).
Tests will fail on SQLite if apps without migrations have relations to apps
with migrations. This has been a documented restriction since migrations were
added in Django 1.7, but it fails more reliably now. You'll see tests failing
with errors like
no such table: <app_label>_<model>. This was observed
with several third-party apps that had models in tests without migrations.
You must add migrations for such models.
Plural equations for some languages are changed, because the latest versions from Transifex are incorporated.
The ability to handle
.po files containing different plural equations
for the same language was added in Django 2.2.12.
Meta.orderingwill no longer affect
GROUP BY queries (such as
.annotate().values()) is a common source of confusion. Such queries now
issue a deprecation warning with the advice to add an
order_by() to retain
the current query.
Meta.ordering will be ignored in such queries starting
in Django 3.1.
django.utils.timezone.FixedOffsetis deprecated in favor of
FloatRangeFieldmodel and form fields in
django.contrib.postgresare deprecated in favor of a new name,
DecimalRangeField, to match the underlying
numrangedata type used in the database.
FILE_CHARSETsetting is deprecated. Starting with Django 3.1, files read from disk must be UTF-8 encoded.
django.contrib.staticfiles.storage.CachedStaticFilesStorageis deprecated due to the intractable problems that it has. Use
ManifestStaticFilesStorageor a third-party cloud storage instead.
RemoteUserBackend.configure_user()is now passed
requestas the first positional argument, if it accepts it. Support for overrides that don't accept it will be removed in Django 3.1.
TestCase.multi_dbattributes are deprecated in favor of
TestCase.databases. These new attributes allow databases dependencies to be declared in order to prevent unexpected queries against non-default databases to leak state between tests. The previous behavior of
multi_db=Truecan be achieved by setting