2023-04-03 09:00:23 +02:00
|
|
|
|
========================
|
|
|
|
|
Django 4.2 release notes
|
|
|
|
|
========================
|
2022-05-10 14:42:13 +02:00
|
|
|
|
|
2023-04-03 09:00:23 +02:00
|
|
|
|
*April 3, 2023*
|
2022-05-10 14:42:13 +02:00
|
|
|
|
|
|
|
|
|
Welcome to Django 4.2!
|
|
|
|
|
|
|
|
|
|
These release notes cover the :ref:`new features <whats-new-4.2>`, as well as
|
|
|
|
|
some :ref:`backwards incompatible changes <backwards-incompatible-4.2>` you'll
|
|
|
|
|
want to be aware of when upgrading from Django 4.1 or earlier. We've
|
|
|
|
|
:ref:`begun the deprecation process for some features
|
|
|
|
|
<deprecated-features-4.2>`.
|
|
|
|
|
|
|
|
|
|
See the :doc:`/howto/upgrade-version` guide if you're updating an existing
|
|
|
|
|
project.
|
|
|
|
|
|
2023-01-17 19:24:31 +01:00
|
|
|
|
Django 4.2 is designated as a :term:`long-term support release
|
|
|
|
|
<Long-term support release>`. It will receive security updates for at least
|
|
|
|
|
three years after its release. Support for the previous LTS, Django 3.2, will
|
|
|
|
|
end in April 2024.
|
|
|
|
|
|
2022-05-10 14:42:13 +02:00
|
|
|
|
Python compatibility
|
|
|
|
|
====================
|
|
|
|
|
|
|
|
|
|
Django 4.2 supports Python 3.8, 3.9, 3.10, and 3.11. We **highly recommend**
|
|
|
|
|
and only officially support the latest release of each series.
|
|
|
|
|
|
|
|
|
|
.. _whats-new-4.2:
|
|
|
|
|
|
|
|
|
|
What's new in Django 4.2
|
|
|
|
|
========================
|
|
|
|
|
|
2022-12-01 20:23:43 +01:00
|
|
|
|
Psycopg 3 support
|
|
|
|
|
-----------------
|
|
|
|
|
|
2023-01-17 05:21:53 +01:00
|
|
|
|
Django now supports `psycopg`_ version 3.1.8 or higher. To update your code,
|
2023-04-17 01:14:09 +02:00
|
|
|
|
install the :pypi:`psycopg library <psycopg>`, you don't need to change the
|
2022-12-01 20:23:43 +01:00
|
|
|
|
:setting:`ENGINE <DATABASE-ENGINE>` as ``django.db.backends.postgresql``
|
|
|
|
|
supports both libraries.
|
|
|
|
|
|
|
|
|
|
Support for ``psycopg2`` is likely to be deprecated and removed at some point
|
|
|
|
|
in the future.
|
|
|
|
|
|
2023-04-04 13:53:13 +02:00
|
|
|
|
Be aware that ``psycopg`` 3 introduces some breaking changes over ``psycopg2``.
|
|
|
|
|
As a consequence, you may need to make some changes to account for
|
|
|
|
|
`differences from psycopg2`_.
|
|
|
|
|
|
2022-12-01 20:23:43 +01:00
|
|
|
|
.. _psycopg: https://www.psycopg.org/psycopg3/
|
2023-04-04 13:53:13 +02:00
|
|
|
|
.. _differences from psycopg2: https://www.psycopg.org/psycopg3/docs/basic/from_pg2.html
|
2022-12-01 20:23:43 +01:00
|
|
|
|
|
2022-10-16 07:59:39 +02:00
|
|
|
|
Comments on columns and tables
|
|
|
|
|
------------------------------
|
|
|
|
|
|
|
|
|
|
The new :attr:`Field.db_comment <django.db.models.Field.db_comment>` and
|
|
|
|
|
:attr:`Meta.db_table_comment <django.db.models.Options.db_table_comment>`
|
|
|
|
|
options allow creating comments on columns and tables, respectively. For
|
|
|
|
|
example::
|
|
|
|
|
|
|
|
|
|
from django.db import models
|
|
|
|
|
|
2023-02-28 20:53:28 +01:00
|
|
|
|
|
2022-10-16 07:59:39 +02:00
|
|
|
|
class Question(models.Model):
|
|
|
|
|
text = models.TextField(db_comment="Poll question")
|
|
|
|
|
pub_date = models.DateTimeField(
|
|
|
|
|
db_comment="Date and time when the question was published",
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
db_table_comment = "Poll questions"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Answer(models.Model):
|
|
|
|
|
question = models.ForeignKey(
|
|
|
|
|
Question,
|
|
|
|
|
on_delete=models.CASCADE,
|
2023-01-15 19:10:05 +01:00
|
|
|
|
db_comment="Reference to a question",
|
2022-10-16 07:59:39 +02:00
|
|
|
|
)
|
|
|
|
|
answer = models.TextField(db_comment="Question answer")
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
db_table_comment = "Question answers"
|
|
|
|
|
|
|
|
|
|
Also, the new :class:`~django.db.migrations.operations.AlterModelTableComment`
|
|
|
|
|
operation allows changing table comments defined in the
|
|
|
|
|
:attr:`Meta.db_table_comment <django.db.models.Options.db_table_comment>`.
|
|
|
|
|
|
2022-11-20 21:46:55 +01:00
|
|
|
|
Mitigation for the BREACH attack
|
|
|
|
|
--------------------------------
|
|
|
|
|
|
|
|
|
|
:class:`~django.middleware.gzip.GZipMiddleware` now includes a mitigation for
|
|
|
|
|
the BREACH attack. It will add up to 100 random bytes to gzip responses to make
|
|
|
|
|
BREACH attacks harder. Read more about the mitigation technique in the `Heal
|
|
|
|
|
The Breach (HTB) paper`_.
|
|
|
|
|
|
|
|
|
|
.. _Heal The Breach (HTB) paper: https://ieeexplore.ieee.org/document/9754554
|
|
|
|
|
|
2022-11-11 07:17:49 +01:00
|
|
|
|
In-memory file storage
|
|
|
|
|
----------------------
|
|
|
|
|
|
2023-01-15 19:10:05 +01:00
|
|
|
|
The new :class:`django.core.files.storage.InMemoryStorage` class provides a
|
2022-11-11 07:17:49 +01:00
|
|
|
|
non-persistent storage useful for speeding up tests by avoiding disk access.
|
|
|
|
|
|
2023-01-11 10:48:57 +01:00
|
|
|
|
Custom file storages
|
|
|
|
|
--------------------
|
|
|
|
|
|
|
|
|
|
The new :setting:`STORAGES` setting allows configuring multiple custom file
|
2022-09-11 17:33:47 +02:00
|
|
|
|
storage backends. It also controls storage engines for managing
|
2023-01-17 19:27:51 +01:00
|
|
|
|
:doc:`files </topics/files>` (the ``"default"`` key) and :doc:`static files
|
2022-09-11 17:33:47 +02:00
|
|
|
|
</ref/contrib/staticfiles>` (the ``"staticfiles"`` key).
|
|
|
|
|
|
|
|
|
|
The old ``DEFAULT_FILE_STORAGE`` and ``STATICFILES_STORAGE`` settings are
|
|
|
|
|
deprecated as of this release.
|
2023-01-11 10:48:57 +01:00
|
|
|
|
|
2022-05-10 14:42:13 +02:00
|
|
|
|
Minor features
|
|
|
|
|
--------------
|
|
|
|
|
|
|
|
|
|
:mod:`django.contrib.admin`
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
2022-07-13 13:51:06 +02:00
|
|
|
|
* The light or dark color theme of the admin can now be toggled in the UI, as
|
|
|
|
|
well as being set to follow the system setting.
|
2022-05-10 14:42:13 +02:00
|
|
|
|
|
2022-08-16 15:44:10 +02:00
|
|
|
|
* The admin's font stack now prefers system UI fonts and no longer requires
|
|
|
|
|
downloading fonts. Additionally, CSS variables are available to more easily
|
|
|
|
|
override the default font families.
|
|
|
|
|
|
2022-08-18 00:57:24 +02:00
|
|
|
|
* The :source:`admin/delete_confirmation.html
|
|
|
|
|
<django/contrib/admin/templates/admin/delete_confirmation.html>` template now
|
|
|
|
|
has some additional blocks and scripting hooks to ease customization.
|
|
|
|
|
|
2022-08-25 21:50:31 +02:00
|
|
|
|
* The chosen options of
|
|
|
|
|
:attr:`~django.contrib.admin.ModelAdmin.filter_horizontal` and
|
|
|
|
|
:attr:`~django.contrib.admin.ModelAdmin.filter_vertical` widgets are now
|
|
|
|
|
filterable.
|
|
|
|
|
|
2022-09-24 17:47:41 +02:00
|
|
|
|
* The ``admin/base.html`` template now has a new block ``nav-breadcrumbs``
|
|
|
|
|
which contains the navigation landmark and the ``breadcrumbs`` block.
|
|
|
|
|
|
2022-09-24 12:12:28 +02:00
|
|
|
|
* :attr:`.ModelAdmin.list_editable` now uses atomic transactions when making
|
|
|
|
|
edits.
|
|
|
|
|
|
2023-03-09 08:55:08 +01:00
|
|
|
|
* jQuery is upgraded from version 3.6.0 to 3.6.4.
|
2023-01-04 11:28:09 +01:00
|
|
|
|
|
2022-05-10 14:42:13 +02:00
|
|
|
|
:mod:`django.contrib.auth`
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
2022-05-10 15:26:17 +02:00
|
|
|
|
* The default iteration count for the PBKDF2 password hasher is increased from
|
2023-02-04 13:37:44 +01:00
|
|
|
|
390,000 to 600,000.
|
2022-05-10 14:42:13 +02:00
|
|
|
|
|
2022-11-27 20:49:02 +01:00
|
|
|
|
* :class:`~django.contrib.auth.forms.UserCreationForm` now saves many-to-many
|
|
|
|
|
form fields for a custom user model.
|
|
|
|
|
|
2022-09-24 16:26:14 +02:00
|
|
|
|
* The new :class:`~django.contrib.auth.forms.BaseUserCreationForm` is now the
|
|
|
|
|
recommended base class for customizing the user creation form.
|
|
|
|
|
|
2022-05-10 14:42:13 +02:00
|
|
|
|
:mod:`django.contrib.gis`
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
2022-05-28 11:33:15 +02:00
|
|
|
|
* The :doc:`GeoJSON serializer </ref/contrib/gis/serializers>` now outputs the
|
|
|
|
|
``id`` key for serialized features, which defaults to the primary key of
|
|
|
|
|
objects.
|
2022-05-10 14:42:13 +02:00
|
|
|
|
|
2022-07-25 18:33:25 +02:00
|
|
|
|
* The :class:`~django.contrib.gis.gdal.GDALRaster` class now supports
|
|
|
|
|
:class:`pathlib.Path`.
|
|
|
|
|
|
2022-07-29 18:34:18 +02:00
|
|
|
|
* The :class:`~django.contrib.gis.geoip2.GeoIP2` class now supports ``.mmdb``
|
|
|
|
|
files downloaded from DB-IP.
|
|
|
|
|
|
2022-07-30 23:52:17 +02:00
|
|
|
|
* The OpenLayers template widget no longer includes inline CSS (which also
|
|
|
|
|
removes the former ``map_css`` block) to better comply with a strict Content
|
|
|
|
|
Security Policy.
|
|
|
|
|
|
2022-12-29 08:30:30 +01:00
|
|
|
|
* :class:`~django.contrib.gis.forms.widgets.OpenLayersWidget` is now based on
|
|
|
|
|
OpenLayers 7.2.2 (previously 4.6.5).
|
|
|
|
|
|
2022-12-31 15:32:35 +01:00
|
|
|
|
* The new :lookup:`isempty` lookup and
|
|
|
|
|
:class:`IsEmpty() <django.contrib.gis.db.models.functions.IsEmpty>`
|
|
|
|
|
expression allow filtering empty geometries on PostGIS.
|
|
|
|
|
|
2023-01-10 11:51:09 +01:00
|
|
|
|
* The new :class:`FromWKB() <django.contrib.gis.db.models.functions.FromWKB>`
|
|
|
|
|
and :class:`FromWKT() <django.contrib.gis.db.models.functions.FromWKT>`
|
|
|
|
|
functions allow creating geometries from Well-known binary (WKB) and
|
|
|
|
|
Well-known text (WKT) representations.
|
|
|
|
|
|
2022-05-10 14:42:13 +02:00
|
|
|
|
:mod:`django.contrib.postgres`
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
2022-06-17 09:44:03 +02:00
|
|
|
|
* The new :lookup:`trigram_strict_word_similar` lookup, and the
|
|
|
|
|
:class:`TrigramStrictWordSimilarity()
|
|
|
|
|
<django.contrib.postgres.search.TrigramStrictWordSimilarity>` and
|
|
|
|
|
:class:`TrigramStrictWordDistance()
|
|
|
|
|
<django.contrib.postgres.search.TrigramStrictWordDistance>` expressions allow
|
|
|
|
|
using trigram strict word similarity.
|
2022-05-10 14:42:13 +02:00
|
|
|
|
|
2022-10-26 15:58:08 +02:00
|
|
|
|
* The :lookup:`arrayfield.overlap` lookup now supports ``QuerySet.values()``
|
|
|
|
|
and ``values_list()`` as a right-hand side.
|
|
|
|
|
|
2022-05-10 14:42:13 +02:00
|
|
|
|
:mod:`django.contrib.sitemaps`
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
2022-10-21 17:36:44 +02:00
|
|
|
|
* The new :meth:`.Sitemap.get_languages_for_item` method allows customizing the
|
|
|
|
|
list of languages for which the item is displayed.
|
2022-05-10 14:42:13 +02:00
|
|
|
|
|
|
|
|
|
:mod:`django.contrib.staticfiles`
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
2022-12-07 10:56:00 +01:00
|
|
|
|
* :class:`~django.contrib.staticfiles.storage.ManifestStaticFilesStorage` now
|
2023-03-18 14:05:41 +01:00
|
|
|
|
has experimental support for replacing paths to JavaScript modules in
|
|
|
|
|
``import`` and ``export`` statements with their hashed counterparts. If you
|
|
|
|
|
want to try it, subclass ``ManifestStaticFilesStorage`` and set the
|
|
|
|
|
``support_js_module_import_aggregation`` attribute to ``True``.
|
2022-05-10 14:42:13 +02:00
|
|
|
|
|
2022-12-29 16:52:56 +01:00
|
|
|
|
* The new :attr:`.ManifestStaticFilesStorage.manifest_hash` attribute provides
|
|
|
|
|
a hash over all files in the manifest and changes whenever one of the files
|
|
|
|
|
changes.
|
|
|
|
|
|
2022-12-06 05:26:37 +01:00
|
|
|
|
Database backends
|
|
|
|
|
~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
* The new ``"assume_role"`` option is now supported in :setting:`OPTIONS` on
|
|
|
|
|
PostgreSQL to allow specifying the :ref:`session role <database-role>`.
|
|
|
|
|
|
2023-01-16 10:22:02 +01:00
|
|
|
|
* The new ``"server_side_binding"`` option is now supported in
|
|
|
|
|
:setting:`OPTIONS` on PostgreSQL with ``psycopg`` 3.1.8+ to allow using
|
|
|
|
|
:ref:`server-side binding cursors <database-server-side-parameters-binding>`.
|
|
|
|
|
|
2022-05-10 14:42:13 +02:00
|
|
|
|
Error Reporting
|
|
|
|
|
~~~~~~~~~~~~~~~
|
|
|
|
|
|
2022-11-03 11:49:10 +01:00
|
|
|
|
* The debug page now shows :pep:`exception notes <678>` and
|
|
|
|
|
:pep:`fine-grained error locations <657>` on Python 3.11+.
|
2022-05-10 14:42:13 +02:00
|
|
|
|
|
2023-01-17 13:08:42 +01:00
|
|
|
|
* Session cookies are now treated as credentials and therefore hidden and
|
|
|
|
|
replaced with stars (``**********``) in error reports.
|
|
|
|
|
|
2022-05-10 14:42:13 +02:00
|
|
|
|
Forms
|
|
|
|
|
~~~~~
|
|
|
|
|
|
2022-08-04 20:39:12 +02:00
|
|
|
|
* :class:`~django.forms.ModelForm` now accepts the new ``Meta`` option
|
|
|
|
|
``formfield_callback`` to customize form fields.
|
|
|
|
|
|
|
|
|
|
* :func:`~django.forms.models.modelform_factory` now respects the
|
|
|
|
|
``formfield_callback`` attribute of the ``form``’s ``Meta``.
|
2022-05-10 14:42:13 +02:00
|
|
|
|
|
|
|
|
|
Internationalization
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
2022-08-13 11:36:15 +02:00
|
|
|
|
* Added support and translations for the Central Kurdish (Sorani) language.
|
2022-05-10 14:42:13 +02:00
|
|
|
|
|
|
|
|
|
Logging
|
|
|
|
|
~~~~~~~
|
|
|
|
|
|
2022-10-21 00:14:35 +02:00
|
|
|
|
* The :ref:`django-db-logger` logger now logs transaction management queries
|
|
|
|
|
(``BEGIN``, ``COMMIT``, and ``ROLLBACK``) at the ``DEBUG`` level.
|
2022-05-10 14:42:13 +02:00
|
|
|
|
|
|
|
|
|
Management Commands
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
2022-03-17 12:02:59 +01:00
|
|
|
|
* :djadmin:`makemessages` command now supports locales with private sub-tags
|
|
|
|
|
such as ``nl_NL-x-informal``.
|
2022-05-10 14:42:13 +02:00
|
|
|
|
|
2022-06-14 20:12:20 +02:00
|
|
|
|
* The new :option:`makemigrations --update` option merges model changes into
|
|
|
|
|
the latest migration and optimizes the resulting operations.
|
|
|
|
|
|
2022-05-10 14:42:13 +02:00
|
|
|
|
Migrations
|
|
|
|
|
~~~~~~~~~~
|
|
|
|
|
|
2022-08-11 18:17:19 +02:00
|
|
|
|
* Migrations now support serialization of ``enum.Flag`` objects.
|
2022-05-10 14:42:13 +02:00
|
|
|
|
|
|
|
|
|
Models
|
|
|
|
|
~~~~~~
|
|
|
|
|
|
2022-08-10 14:22:01 +02:00
|
|
|
|
* ``QuerySet`` now extensively supports filtering against
|
|
|
|
|
:ref:`window-functions` with the exception of disjunctive filter lookups
|
|
|
|
|
against window functions when performing aggregation.
|
2022-05-10 14:42:13 +02:00
|
|
|
|
|
2022-08-13 08:14:19 +02:00
|
|
|
|
* :meth:`~.QuerySet.prefetch_related` now supports
|
|
|
|
|
:class:`~django.db.models.Prefetch` objects with sliced querysets.
|
|
|
|
|
|
2022-06-23 08:32:53 +02:00
|
|
|
|
* :ref:`Registering lookups <lookup-registration-api>` on
|
|
|
|
|
:class:`~django.db.models.Field` instances is now supported.
|
|
|
|
|
|
2022-06-07 17:50:46 +02:00
|
|
|
|
* The new ``robust`` argument for :func:`~django.db.transaction.on_commit`
|
|
|
|
|
allows performing actions that can fail after a database transaction is
|
|
|
|
|
successfully committed.
|
|
|
|
|
|
2022-08-30 19:26:18 +02:00
|
|
|
|
* The new :class:`KT() <django.db.models.fields.json.KT>` expression represents
|
|
|
|
|
the text value of a key, index, or path transform of
|
|
|
|
|
:class:`~django.db.models.JSONField`.
|
|
|
|
|
|
2022-09-25 14:32:05 +02:00
|
|
|
|
* :class:`~django.db.models.functions.Now` now supports microsecond precision
|
|
|
|
|
on MySQL and millisecond precision on SQLite.
|
|
|
|
|
|
2022-09-26 22:59:25 +02:00
|
|
|
|
* :class:`F() <django.db.models.F>` expressions that output ``BooleanField``
|
|
|
|
|
can now be negated using ``~F()`` (inversion operator).
|
|
|
|
|
|
2022-10-30 17:51:54 +01:00
|
|
|
|
* ``Model`` now provides asynchronous versions of some methods that use the
|
|
|
|
|
database, using an ``a`` prefix: :meth:`~.Model.adelete`,
|
|
|
|
|
:meth:`~.Model.arefresh_from_db`, and :meth:`~.Model.asave`.
|
|
|
|
|
|
2022-11-03 19:57:33 +01:00
|
|
|
|
* Related managers now provide asynchronous versions of methods that change a
|
|
|
|
|
set of related objects, using an ``a`` prefix: :meth:`~.RelatedManager.aadd`,
|
|
|
|
|
:meth:`~.RelatedManager.aclear`, :meth:`~.RelatedManager.aremove`, and
|
|
|
|
|
:meth:`~.RelatedManager.aset`.
|
|
|
|
|
|
2022-11-10 19:31:31 +01:00
|
|
|
|
* :attr:`CharField.max_length <django.db.models.CharField.max_length>` is no
|
|
|
|
|
longer required to be set on PostgreSQL, which supports unlimited ``VARCHAR``
|
|
|
|
|
columns.
|
|
|
|
|
|
2022-05-10 14:42:13 +02:00
|
|
|
|
Requests and Responses
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
2022-12-13 16:15:25 +01:00
|
|
|
|
* :class:`~django.http.StreamingHttpResponse` now supports async iterators
|
|
|
|
|
when Django is served via ASGI.
|
2022-05-10 14:42:13 +02:00
|
|
|
|
|
|
|
|
|
Tests
|
|
|
|
|
~~~~~
|
|
|
|
|
|
2022-10-21 00:37:27 +02:00
|
|
|
|
* The :option:`test --debug-sql` option now formats SQL queries with
|
|
|
|
|
``sqlparse``.
|
2022-05-10 14:42:13 +02:00
|
|
|
|
|
2022-10-09 22:33:35 +02:00
|
|
|
|
* The :class:`~django.test.RequestFactory`,
|
|
|
|
|
:class:`~django.test.AsyncRequestFactory`, :class:`~django.test.Client`, and
|
|
|
|
|
:class:`~django.test.AsyncClient` classes now support the ``headers``
|
|
|
|
|
parameter, which accepts a dictionary of header names and values. This allows
|
|
|
|
|
a more natural syntax for declaring headers.
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
# Before:
|
|
|
|
|
self.client.get("/home/", HTTP_ACCEPT_LANGUAGE="fr")
|
|
|
|
|
await self.async_client.get("/home/", ACCEPT_LANGUAGE="fr")
|
|
|
|
|
|
|
|
|
|
# After:
|
|
|
|
|
self.client.get("/home/", headers={"accept-language": "fr"})
|
|
|
|
|
await self.async_client.get("/home/", headers={"accept-language": "fr"})
|
|
|
|
|
|
2022-05-10 14:42:13 +02:00
|
|
|
|
Utilities
|
|
|
|
|
~~~~~~~~~
|
|
|
|
|
|
2022-06-23 10:50:20 +02:00
|
|
|
|
* The new ``encoder`` parameter for :meth:`django.utils.html.json_script`
|
|
|
|
|
function allows customizing a JSON encoder class.
|
2022-05-10 14:42:13 +02:00
|
|
|
|
|
2022-06-30 02:39:51 +02:00
|
|
|
|
* The private internal vendored copy of ``urllib.parse.urlsplit()`` now strips
|
|
|
|
|
``'\r'``, ``'\n'``, and ``'\t'`` (see :cve:`2022-0391` and :bpo:`43882`).
|
|
|
|
|
This is to protect projects that may be incorrectly using the internal
|
|
|
|
|
``url_has_allowed_host_and_scheme()`` function, instead of using one of the
|
|
|
|
|
documented functions for handling URL redirects. The Django functions were
|
|
|
|
|
not affected.
|
|
|
|
|
|
2022-11-30 21:09:49 +01:00
|
|
|
|
* The new :func:`django.utils.http.content_disposition_header` function returns
|
|
|
|
|
a ``Content-Disposition`` HTTP header value as specified by :rfc:`6266`.
|
|
|
|
|
|
2022-05-10 14:42:13 +02:00
|
|
|
|
Validators
|
|
|
|
|
~~~~~~~~~~
|
|
|
|
|
|
2022-09-28 11:27:10 +02:00
|
|
|
|
* The list of common passwords used by ``CommonPasswordValidator`` is updated
|
|
|
|
|
to the most recent version.
|
2022-05-10 14:42:13 +02:00
|
|
|
|
|
|
|
|
|
.. _backwards-incompatible-4.2:
|
|
|
|
|
|
|
|
|
|
Backwards incompatible changes in 4.2
|
|
|
|
|
=====================================
|
|
|
|
|
|
|
|
|
|
Database backend API
|
|
|
|
|
--------------------
|
|
|
|
|
|
|
|
|
|
This section describes changes that may be needed in third-party database
|
|
|
|
|
backends.
|
|
|
|
|
|
2022-11-05 17:49:33 +01:00
|
|
|
|
* ``DatabaseFeatures.allows_group_by_pk`` is removed as it only remained to
|
|
|
|
|
accommodate a MySQL extension that has been supplanted by proper functional
|
|
|
|
|
dependency detection in MySQL 5.7.15. Note that
|
|
|
|
|
``DatabaseFeatures.allows_group_by_selected_pks`` is still supported and
|
|
|
|
|
should be enabled if your backend supports functional dependency detection in
|
|
|
|
|
``GROUP BY`` clauses as specified by the ``SQL:1999`` standard.
|
2022-05-10 14:42:13 +02:00
|
|
|
|
|
2023-02-22 05:17:02 +01:00
|
|
|
|
* :djadmin:`inspectdb` now uses ``display_size`` from
|
|
|
|
|
``DatabaseIntrospection.get_table_description()`` rather than
|
|
|
|
|
``internal_size`` for ``CharField``.
|
|
|
|
|
|
2022-05-18 08:38:08 +02:00
|
|
|
|
Dropped support for MariaDB 10.3
|
|
|
|
|
--------------------------------
|
|
|
|
|
|
|
|
|
|
Upstream support for MariaDB 10.3 ends in May 2023. Django 4.2 supports MariaDB
|
|
|
|
|
10.4 and higher.
|
|
|
|
|
|
2022-07-08 13:30:12 +02:00
|
|
|
|
Dropped support for MySQL 5.7
|
|
|
|
|
-----------------------------
|
|
|
|
|
|
|
|
|
|
Upstream support for MySQL 5.7 ends in October 2023. Django 4.2 supports MySQL
|
|
|
|
|
8 and higher.
|
|
|
|
|
|
2022-05-19 09:26:48 +02:00
|
|
|
|
Dropped support for PostgreSQL 11
|
|
|
|
|
---------------------------------
|
|
|
|
|
|
|
|
|
|
Upstream support for PostgreSQL 11 ends in November 2023. Django 4.2 supports
|
|
|
|
|
PostgreSQL 12 and higher.
|
|
|
|
|
|
2022-11-11 09:43:50 +01:00
|
|
|
|
Setting ``update_fields`` in ``Model.save()`` may now be required
|
|
|
|
|
-----------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
In order to avoid updating unnecessary columns,
|
|
|
|
|
:meth:`.QuerySet.update_or_create` now passes ``update_fields`` to the
|
|
|
|
|
:meth:`Model.save() <django.db.models.Model.save>` calls. As a consequence, any
|
|
|
|
|
fields modified in the custom ``save()`` methods should be added to the
|
|
|
|
|
``update_fields`` keyword argument before calling ``super()``. See
|
|
|
|
|
:ref:`overriding-model-methods` for more details.
|
|
|
|
|
|
2022-05-10 14:42:13 +02:00
|
|
|
|
Miscellaneous
|
|
|
|
|
-------------
|
|
|
|
|
|
2022-06-28 21:45:03 +02:00
|
|
|
|
* The undocumented ``django.http.multipartparser.parse_header()`` function is
|
|
|
|
|
removed. Use ``django.utils.http.parse_header_parameters()`` instead.
|
|
|
|
|
|
2022-07-14 08:11:17 +02:00
|
|
|
|
* :ttag:`{% blocktranslate asvar … %}<blocktranslate>` result is now marked as
|
|
|
|
|
safe for (HTML) output purposes.
|
|
|
|
|
|
2022-09-26 21:06:48 +02:00
|
|
|
|
* The ``autofocus`` HTML attribute in the admin search box is removed as it can
|
|
|
|
|
be confusing for screen readers.
|
|
|
|
|
|
2022-09-26 01:53:55 +02:00
|
|
|
|
* The :option:`makemigrations --check` option no longer creates missing
|
|
|
|
|
migration files.
|
|
|
|
|
|
2022-09-28 16:51:06 +02:00
|
|
|
|
* The ``alias`` argument for :meth:`.Expression.get_group_by_cols` is removed.
|
|
|
|
|
|
2022-10-21 00:37:27 +02:00
|
|
|
|
* The minimum supported version of ``sqlparse`` is increased from 0.2.2 to
|
2023-01-05 18:09:33 +01:00
|
|
|
|
0.3.1.
|
2022-10-21 00:37:27 +02:00
|
|
|
|
|
2022-09-26 22:59:25 +02:00
|
|
|
|
* The undocumented ``negated`` parameter of the
|
|
|
|
|
:class:`~django.db.models.Exists` expression is removed.
|
|
|
|
|
|
2022-11-23 03:49:12 +01:00
|
|
|
|
* The ``is_summary`` argument of the undocumented ``Query.add_annotation()``
|
|
|
|
|
method is removed.
|
|
|
|
|
|
2022-12-08 05:53:18 +01:00
|
|
|
|
* The minimum supported version of SQLite is increased from 3.9.0 to 3.21.0.
|
|
|
|
|
|
2022-12-20 11:10:48 +01:00
|
|
|
|
* The minimum supported version of ``asgiref`` is increased from 3.5.2 to
|
|
|
|
|
3.6.0.
|
|
|
|
|
|
2022-09-24 16:26:14 +02:00
|
|
|
|
* :class:`~django.contrib.auth.forms.UserCreationForm` now rejects usernames
|
|
|
|
|
that differ only in case. If you need the previous behavior, use
|
|
|
|
|
:class:`~django.contrib.auth.forms.BaseUserCreationForm` instead.
|
|
|
|
|
|
2023-01-05 16:34:14 +01:00
|
|
|
|
* The minimum supported version of ``mysqlclient`` is increased from 1.4.0 to
|
|
|
|
|
1.4.3.
|
|
|
|
|
|
2023-01-05 18:09:33 +01:00
|
|
|
|
* The minimum supported version of ``argon2-cffi`` is increased from 19.1.0 to
|
|
|
|
|
19.2.0.
|
|
|
|
|
|
|
|
|
|
* The minimum supported version of ``Pillow`` is increased from 6.2.0 to 6.2.1.
|
|
|
|
|
|
|
|
|
|
* The minimum supported version of ``jinja2`` is increased from 2.9.2 to
|
|
|
|
|
2.11.0.
|
|
|
|
|
|
2023-04-17 01:14:09 +02:00
|
|
|
|
* The minimum supported version of :pypi:`redis-py <redis>` is increased from
|
|
|
|
|
3.0.0 to 3.4.0.
|
2023-01-05 18:09:33 +01:00
|
|
|
|
|
2022-07-22 22:08:10 +02:00
|
|
|
|
* Manually instantiated ``WSGIRequest`` objects must be provided a file-like
|
|
|
|
|
object for ``wsgi.input``. Previously, Django was more lax than the expected
|
|
|
|
|
behavior as specified by the WSGI specification.
|
|
|
|
|
|
2023-01-11 18:30:10 +01:00
|
|
|
|
* Support for ``PROJ`` < 5 is removed.
|
|
|
|
|
|
2023-04-28 13:04:08 +02:00
|
|
|
|
* :class:`~django.core.mail.backends.smtp.EmailBackend` now verifies a
|
|
|
|
|
:py:attr:`hostname <ssl.SSLContext.check_hostname>` and
|
|
|
|
|
:py:attr:`certificates <ssl.SSLContext.verify_mode>`. If you need the
|
|
|
|
|
previous behavior that is less restrictive and not recommended, subclass
|
|
|
|
|
``EmailBackend`` and override the ``ssl_context`` property.
|
|
|
|
|
|
2022-05-10 14:42:13 +02:00
|
|
|
|
.. _deprecated-features-4.2:
|
|
|
|
|
|
|
|
|
|
Features deprecated in 4.2
|
|
|
|
|
==========================
|
|
|
|
|
|
2022-05-17 16:13:35 +02:00
|
|
|
|
``index_together`` option is deprecated in favor of ``indexes``
|
|
|
|
|
---------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
The :attr:`Meta.index_together <django.db.models.Options.index_together>`
|
|
|
|
|
option is deprecated in favor of the :attr:`~django.db.models.Options.indexes`
|
|
|
|
|
option.
|
|
|
|
|
|
|
|
|
|
Migrating existing ``index_together`` should be handled as a migration. For
|
|
|
|
|
example::
|
|
|
|
|
|
|
|
|
|
class Author(models.Model):
|
|
|
|
|
rank = models.IntegerField()
|
|
|
|
|
name = models.CharField(max_length=30)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
index_together = [["rank", "name"]]
|
|
|
|
|
|
|
|
|
|
Should become::
|
|
|
|
|
|
|
|
|
|
class Author(models.Model):
|
2022-08-03 18:40:42 +02:00
|
|
|
|
rank = models.IntegerField()
|
2022-05-17 16:13:35 +02:00
|
|
|
|
name = models.CharField(max_length=30)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
indexes = [models.Index(fields=["rank", "name"])]
|
|
|
|
|
|
|
|
|
|
Running the :djadmin:`makemigrations` command will generate a migration
|
|
|
|
|
containing a :class:`~django.db.migrations.operations.RenameIndex` operation
|
|
|
|
|
which will rename the existing index.
|
|
|
|
|
|
2022-07-20 07:56:02 +02:00
|
|
|
|
The ``AlterIndexTogether`` migration operation is now officially supported only
|
|
|
|
|
for pre-Django 4.2 migration files. For backward compatibility reasons, it's
|
|
|
|
|
still part of the public API, and there's no plan to deprecate or remove it,
|
|
|
|
|
but it should not be used for new migrations. Use
|
|
|
|
|
:class:`~django.db.migrations.operations.AddIndex` and
|
|
|
|
|
:class:`~django.db.migrations.operations.RemoveIndex` operations instead.
|
|
|
|
|
|
2022-11-03 03:03:05 +01:00
|
|
|
|
Passing encoded JSON string literals to ``JSONField`` is deprecated
|
|
|
|
|
-------------------------------------------------------------------
|
|
|
|
|
|
2023-01-15 19:10:05 +01:00
|
|
|
|
``JSONField`` and its associated lookups and aggregates used to allow passing
|
2022-11-03 03:03:05 +01:00
|
|
|
|
JSON encoded string literals which caused ambiguity on whether string literals
|
|
|
|
|
were already encoded from database backend's perspective.
|
|
|
|
|
|
|
|
|
|
During the deprecation period string literals will be attempted to be JSON
|
|
|
|
|
decoded and a warning will be emitted on success that points at passing
|
|
|
|
|
non-encoded forms instead.
|
|
|
|
|
|
|
|
|
|
Code that use to pass JSON encoded string literals::
|
|
|
|
|
|
|
|
|
|
Document.objects.bulk_create(
|
|
|
|
|
Document(data=Value("null")),
|
|
|
|
|
Document(data=Value("[]")),
|
|
|
|
|
Document(data=Value('"foo-bar"')),
|
|
|
|
|
)
|
|
|
|
|
Document.objects.annotate(
|
|
|
|
|
JSONBAgg("field", default=Value("[]")),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
Should become::
|
|
|
|
|
|
|
|
|
|
Document.objects.bulk_create(
|
|
|
|
|
Document(data=Value(None, JSONField())),
|
|
|
|
|
Document(data=[]),
|
|
|
|
|
Document(data="foo-bar"),
|
|
|
|
|
)
|
|
|
|
|
Document.objects.annotate(
|
|
|
|
|
JSONBAgg("field", default=[]),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
From Django 5.1+ string literals will be implicitly interpreted as JSON string
|
|
|
|
|
literals.
|
|
|
|
|
|
2022-05-10 14:42:13 +02:00
|
|
|
|
Miscellaneous
|
|
|
|
|
-------------
|
|
|
|
|
|
2022-06-02 15:40:20 +02:00
|
|
|
|
* The ``BaseUserManager.make_random_password()`` method is deprecated. See
|
|
|
|
|
`recipes and best practices
|
|
|
|
|
<https://docs.python.org/3/library/secrets.html#recipes-and-best-practices>`_
|
|
|
|
|
for using Python's :py:mod:`secrets` module to generate passwords.
|
2022-05-17 16:13:35 +02:00
|
|
|
|
|
2021-04-22 17:55:59 +02:00
|
|
|
|
* The ``length_is`` template filter is deprecated in favor of :tfilter:`length`
|
|
|
|
|
and the ``==`` operator within an :ttag:`{% if %}<if>` tag. For example
|
|
|
|
|
|
|
|
|
|
.. code-block:: html+django
|
|
|
|
|
|
|
|
|
|
{% if value|length == 4 %}…{% endif %}
|
|
|
|
|
{% if value|length == 4 %}True{% else %}False{% endif %}
|
|
|
|
|
|
|
|
|
|
instead of:
|
|
|
|
|
|
|
|
|
|
.. code-block:: html+django
|
|
|
|
|
|
|
|
|
|
{% if value|length_is:4 %}…{% endif %}
|
|
|
|
|
{{ value|length_is:4 }}
|
2022-07-23 12:45:24 +02:00
|
|
|
|
|
|
|
|
|
* ``django.contrib.auth.hashers.SHA1PasswordHasher``,
|
|
|
|
|
``django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher``, and
|
|
|
|
|
``django.contrib.auth.hashers.UnsaltedMD5PasswordHasher`` are deprecated.
|
2022-08-03 11:42:51 +02:00
|
|
|
|
|
|
|
|
|
* ``django.contrib.postgres.fields.CICharField`` is deprecated in favor of
|
|
|
|
|
``CharField(db_collation="…")`` with a case-insensitive non-deterministic
|
|
|
|
|
collation.
|
|
|
|
|
|
|
|
|
|
* ``django.contrib.postgres.fields.CIEmailField`` is deprecated in favor of
|
|
|
|
|
``EmailField(db_collation="…")`` with a case-insensitive non-deterministic
|
|
|
|
|
collation.
|
|
|
|
|
|
|
|
|
|
* ``django.contrib.postgres.fields.CITextField`` is deprecated in favor of
|
|
|
|
|
``TextField(db_collation="…")`` with a case-insensitive non-deterministic
|
|
|
|
|
collation.
|
|
|
|
|
|
|
|
|
|
* ``django.contrib.postgres.fields.CIText`` mixin is deprecated.
|
2022-08-12 12:18:51 +02:00
|
|
|
|
|
|
|
|
|
* The ``map_height`` and ``map_width`` attributes of ``BaseGeometryWidget`` are
|
|
|
|
|
deprecated, use CSS to size map widgets instead.
|
2022-09-24 12:29:58 +02:00
|
|
|
|
|
|
|
|
|
* ``SimpleTestCase.assertFormsetError()`` is deprecated in favor of
|
|
|
|
|
``assertFormSetError()``.
|
2022-09-24 12:29:58 +02:00
|
|
|
|
|
|
|
|
|
* ``TransactionTestCase.assertQuerysetEqual()`` is deprecated in favor of
|
|
|
|
|
``assertQuerySetEqual()``.
|
2022-11-30 08:03:36 +01:00
|
|
|
|
|
|
|
|
|
* Passing positional arguments to ``Signer`` and ``TimestampSigner`` is
|
|
|
|
|
deprecated in favor of keyword-only arguments.
|
2022-09-11 17:33:47 +02:00
|
|
|
|
|
|
|
|
|
* The ``DEFAULT_FILE_STORAGE`` setting is deprecated in favor of
|
|
|
|
|
``STORAGES["default"]``.
|
|
|
|
|
|
|
|
|
|
* The ``STATICFILES_STORAGE`` setting is deprecated in favor of
|
|
|
|
|
``STORAGES["staticfiles"]``.
|
|
|
|
|
|
|
|
|
|
* The ``django.core.files.storage.get_storage_class()`` function is deprecated.
|