============================================ Django 2.2 release notes - UNDER DEVELOPMENT ============================================ *Expected April 2019* Welcome to Django 2.2! These release notes cover the :ref:`new features `, as well as some :ref:`backwards incompatible changes ` you'll want to be aware of when upgrading from Django 2.1 or earlier. We've :ref:`begun the deprecation process for some features `. See the :doc:`/howto/upgrade-version` guide if you're updating an existing project. Django 2.2 is designated as a :term:`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. Python compatibility ==================== Django 2.2 supports Python 3.5, 3.6, and 3.7. We **highly recommend** and only officially support the latest release of each series. .. _whats-new-2.2: What's new in Django 2.2 ======================== Check Constraints ----------------- The new :class:`~django.db.models.CheckConstraint` class enables adding custom database constraints. Constraints are added to models using the :attr:`Meta.constraints ` option. Minor features -------------- :mod:`django.contrib.admin` ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ... :mod:`django.contrib.admindocs` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ... :mod:`django.contrib.auth` ~~~~~~~~~~~~~~~~~~~~~~~~~~ * ... :mod:`django.contrib.contenttypes` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ... :mod:`django.contrib.gis` ~~~~~~~~~~~~~~~~~~~~~~~~~ * Added Oracle support for the :class:`~django.contrib.gis.db.models.functions.Envelope` function. * Added SpatiaLite support for the :lookup:`coveredby` and :lookup:`covers` lookups. :mod:`django.contrib.messages` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ... :mod:`django.contrib.postgres` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * The new ``ordering`` argument for :class:`~django.contrib.postgres.aggregates.ArrayAgg` and :class:`~django.contrib.postgres.aggregates.StringAgg` determines the ordering of the aggregated elements. * The new :class:`~django.contrib.postgres.indexes.BTreeIndex`, :class:`~django.contrib.postgres.indexes.HashIndex` and :class:`~django.contrib.postgres.indexes.SpGistIndex` classes allow creating ``B-Tree``, ``hash``, and ``SP-GiST`` indexes in the database. * :class:`~django.contrib.postgres.indexes.BrinIndex` now has the ``autosummarize`` parameter. * The new ``search_type`` parameter of :class:`~django.contrib.postgres.search.SearchQuery` allows searching for a phrase or raw expression. :mod:`django.contrib.redirects` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ... :mod:`django.contrib.sessions` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ... :mod:`django.contrib.sitemaps` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ... :mod:`django.contrib.sites` ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ... :mod:`django.contrib.staticfiles` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Added path matching to the :option:`collectstatic --ignore` option so that patterns like ``/vendor/*.js`` can be used. :mod:`django.contrib.syndication` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ... Cache ~~~~~ * ... CSRF ~~~~ * ... Database backends ~~~~~~~~~~~~~~~~~ * Added result streaming for :meth:`.QuerySet.iterator` on SQLite. Email ~~~~~ * ... File Storage ~~~~~~~~~~~~ * ... File Uploads ~~~~~~~~~~~~ * ... Forms ~~~~~ * ... Generic Views ~~~~~~~~~~~~~ * ... Internationalization ~~~~~~~~~~~~~~~~~~~~ * ... Management Commands ~~~~~~~~~~~~~~~~~~~ * The new :option:`--force-color` option forces colorization of the command output. * :djadmin:`inspectdb` now creates models for foreign tables on PostgreSQL. * :option:`inspectdb --include-views` now creates models for materialized views on PostgreSQL. * :djadmin:`inspectdb` now introspects :class:`~django.db.models.DurationField` for Oracle and PostgreSQL. * On Oracle, :djadmin:`dbshell` is wrapped with ``rlwrap``, if available. ``rlwrap`` provides a command history and editing of keyboard input. Migrations ~~~~~~~~~~ * The new :option:`migrate --plan` option prints the list of migration operations that will be performed. * ``NoneType`` can now be serialized in migrations. Models ~~~~~~ * Added support for PostgreSQL operator classes (:attr:`.Index.opclasses`). * Added support for partial indexes (:attr:`.Index.condition`). * Added many :ref:`math database functions `. * Setting the new ``ignore_conflicts`` parameter of :meth:`.QuerySet.bulk_create` to ``True`` tells the database to ignore failure to insert rows that fail uniqueness constraints or other checks. * The new :class:`~django.db.models.functions.ExtractIsoYear` function extracts ISO-8601 week-numbering years from :class:`~django.db.models.DateField` and :class:`~django.db.models.DateTimeField`, and the new :lookup:`iso_year` lookup allows querying by an ISO-8601 week-numbering year. * The new :meth:`.QuerySet.bulk_update` method allows efficiently updating specific fields on multiple model instances. * Django no longer always starts a transaction when a single query is being performed, such as ``Model.save()``, ``QuerySet.update()``, and ``Model.delete()``. This improves the performance of autocommit by reducing the number of database round trips. Requests and Responses ~~~~~~~~~~~~~~~~~~~~~~ * ... Serialization ~~~~~~~~~~~~~ * You can now deserialize data using natural keys containing :ref:`forward references ` by passing ``handle_forward_references=True`` to ``serializers.deserialize()``. Additionally, :djadmin:`loaddata` handles forward references automatically. Signals ~~~~~~~ * ... Templates ~~~~~~~~~ * ... Tests ~~~~~ * The new :meth:`.SimpleTestCase.assertURLEqual` assertion checks for a given URL, ignoring the ordering of the query string. :meth:`~.SimpleTestCase.assertRedirects` uses the new assertion. * The test :class:`~.django.test.Client` now supports automatic JSON serialization of list and tuple ``data`` when ``content_type='application/json'``. URLs ~~~~ * ... Validators ~~~~~~~~~~ * :class:`.MaxValueValidator`, :class:`.MinValueValidator`, :class:`.MinLengthValidator`, and :class:`.MaxLengthValidator` now accept a callable ``limit_value``. .. _backwards-incompatible-2.2: Backwards incompatible changes in 2.2 ===================================== Database backend API -------------------- * Third-party database backends must implement support for table check constraints or set ``DatabaseFeatures.supports_table_check_constraints`` to ``False``. * Third party database backends must implement support for ignoring constraints or uniqueness errors while inserting or set ``DatabaseFeatures.supports_ignore_conflicts`` to ``False``. * Third party database backends must implement introspection for ``DurationField`` or set ``DatabaseFeatures.can_introspect_duration_field`` to ``False``. * ``DatabaseFeatures.uses_savepoints`` now defaults to ``True``. * Third party database backends must implement support for partial indexes or set ``DatabaseFeatures.supports_partial_indexes`` to ``False``. Admin actions are no longer collected from base ``ModelAdmin`` classes ---------------------------------------------------------------------- For example, in older versions of Django:: from django.contrib import admin class BaseAdmin(admin.ModelAdmin): actions = ['a'] class SubAdmin(BaseAdmin): actions = ['b'] ``SubAdmin`` will have actions ``'a'`` and ``'b'``. Now ``actions`` follows standard Python inheritance. To get the same result as before:: class SubAdmin(BaseAdmin): actions = BaseAdmin.actions + ['b'] :mod:`django.contrib.gis` ------------------------- * Support for GDAL 1.9 and 1.10 is dropped. ``TransactionTestCase`` serialized data loading ----------------------------------------------- Initial data migrations are now loaded in :class:`~django.test.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 :option:`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 :class:`~django.test.TransactionTestCase`'s internals. Miscellaneous ------------- * To improve readability, the ``UUIDField`` form field now displays values with dashes, e.g. ``550e8400-e29b-41d4-a716-446655440000`` instead of ``550e8400e29b41d4a716446655440000``. * On SQLite, ``PositiveIntegerField`` and ``PositiveSmallIntegerField`` now 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 see ``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 :func:`django.utils.text.slugify` is no longer marked as HTML safe. * The default truncation character used by the :tfilter:`urlizetrunc`, :tfilter:`truncatechars`, :tfilter:`truncatechars_html`, :tfilter:`truncatewords`, and :tfilter:`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. * :func:`django.utils.http.urlsafe_base64_encode` now returns a string instead of a bytestring, and :func:`django.utils.http.urlsafe_base64_decode` may no longer be passed a bytestring. * Support for ``cx_Oracle`` < 6.0 is removed. .. _deprecated-features-2.2: Features deprecated in 2.2 ========================== Model ``Meta.ordering`` will no longer affect ``GROUP BY`` queries ------------------------------------------------------------------ A model's ``Meta.ordering`` affecting ``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. Miscellaneous ------------- * ``django.utils.timezone.FixedOffset`` is deprecated in favor of :class:`datetime.timezone`. * The undocumented ``QuerySetPaginator`` alias of ``django.core.paginator.Paginator`` is deprecated. * The ``FloatRangeField`` model and form fields in ``django.contrib.postgres`` are deprecated in favor of a new name, ``DecimalRangeField``, to match the underlying ``numrange`` data type used in the database. * The ``FILE_CHARSET`` setting is deprecated. Starting with Django 3.1, files read from disk must be UTF-8 encoded. * ``django.contrib.staticfiles.storage.CachedStaticFilesStorage`` is deprecated due to the intractable problems that is has. Use :class:`.ManifestStaticFilesStorage` or a third-party cloud storage instead.