4.1.txt 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. ============================================
  2. Django 4.1 release notes - UNDER DEVELOPMENT
  3. ============================================
  4. *Expected August 2022*
  5. Welcome to Django 4.1!
  6. These release notes cover the :ref:`new features <whats-new-4.1>`, as well as
  7. some :ref:`backwards incompatible changes <backwards-incompatible-4.1>` you'll
  8. want to be aware of when upgrading from Django 4.0 or earlier. We've
  9. :ref:`begun the deprecation process for some features
  10. <deprecated-features-4.1>`.
  11. See the :doc:`/howto/upgrade-version` guide if you're updating an existing
  12. project.
  13. Python compatibility
  14. ====================
  15. Django 4.1 supports Python 3.8, 3.9, and 3.10. We **highly recommend** and only
  16. officially support the latest release of each series.
  17. .. _whats-new-4.1:
  18. What's new in Django 4.1
  19. ========================
  20. .. _csrf-cookie-masked-usage:
  21. ``CSRF_COOKIE_MASKED`` setting
  22. ------------------------------
  23. The new :setting:`CSRF_COOKIE_MASKED` transitional setting allows specifying
  24. whether to mask the CSRF cookie.
  25. :class:`~django.middleware.csrf.CsrfViewMiddleware` no longer masks the CSRF
  26. cookie like it does the CSRF token in the DOM. If you are upgrading multiple
  27. instances of the same project to Django 4.1, you should set
  28. :setting:`CSRF_COOKIE_MASKED` to ``True`` during the transition, in
  29. order to allow compatibility with the older versions of Django. Once the
  30. transition to 4.1 is complete you can stop overriding
  31. :setting:`CSRF_COOKIE_MASKED`.
  32. This setting is deprecated as of this release and will be removed in Django
  33. 5.0.
  34. Minor features
  35. --------------
  36. :mod:`django.contrib.admin`
  37. ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  38. * The admin :ref:`dark mode CSS variables <admin-theming>` are now applied in a
  39. separate stylesheet and template block.
  40. * :ref:`modeladmin-list-filters` providing custom ``FieldListFilter``
  41. subclasses can now control the query string value separator when filtering
  42. for multiple values using the ``__in`` lookup.
  43. * The admin :meth:`history view <django.contrib.admin.ModelAdmin.history_view>`
  44. is now paginated.
  45. * Related widget wrappers now have a link to object's change form.
  46. :mod:`django.contrib.admindocs`
  47. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  48. * ...
  49. :mod:`django.contrib.auth`
  50. ~~~~~~~~~~~~~~~~~~~~~~~~~~
  51. * The default iteration count for the PBKDF2 password hasher is increased from
  52. 320,000 to 390,000.
  53. :mod:`django.contrib.contenttypes`
  54. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  55. * ...
  56. :mod:`django.contrib.gis`
  57. ~~~~~~~~~~~~~~~~~~~~~~~~~
  58. * The new :meth:`.GEOSGeometry.make_valid()` method allows converting invalid
  59. geometries to valid ones.
  60. :mod:`django.contrib.messages`
  61. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  62. * ...
  63. :mod:`django.contrib.postgres`
  64. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  65. * The new :class:`BitXor() <django.contrib.postgres.aggregates.BitXor>`
  66. aggregate function returns an ``int`` of the bitwise ``XOR`` of all non-null
  67. input values.
  68. * :class:`~django.contrib.postgres.indexes.SpGistIndex` now supports covering
  69. indexes on PostgreSQL 14+.
  70. * :class:`~django.contrib.postgres.constraints.ExclusionConstraint` now
  71. supports covering exclusion constraints using SP-GiST indexes on PostgreSQL
  72. 14+.
  73. * The new ``default_bounds`` attribute of :attr:`DateTimeRangeField
  74. <django.contrib.postgres.fields.DateTimeRangeField.default_bounds>` and
  75. :attr:`DecimalRangeField
  76. <django.contrib.postgres.fields.DecimalRangeField.default_bounds>` allows
  77. specifying bounds for list and tuple inputs.
  78. * :class:`~django.contrib.postgres.constraints.ExclusionConstraint` now allows
  79. specifying operator classes with the
  80. :class:`OpClass() <django.contrib.postgres.indexes.OpClass>` expression.
  81. :mod:`django.contrib.redirects`
  82. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  83. * ...
  84. :mod:`django.contrib.sessions`
  85. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  86. * ...
  87. :mod:`django.contrib.sitemaps`
  88. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  89. * The default sitemap index template ``<sitemapindex>`` now includes the
  90. ``<lastmod>`` timestamp where available, through the new
  91. :meth:`~django.contrib.sitemaps.Sitemap.get_latest_lastmod` method. Custom
  92. sitemap index templates should be updated for the adjusted :ref:`context
  93. variables <sitemap-index-context-variables>`.
  94. :mod:`django.contrib.sites`
  95. ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  96. * ...
  97. :mod:`django.contrib.staticfiles`
  98. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  99. * :class:`~django.contrib.staticfiles.storage.ManifestStaticFilesStorage` now
  100. replaces paths to CSS source map references with their hashed counterparts.
  101. :mod:`django.contrib.syndication`
  102. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  103. * ...
  104. Cache
  105. ~~~~~
  106. * ...
  107. CSRF
  108. ~~~~
  109. * ...
  110. Database backends
  111. ~~~~~~~~~~~~~~~~~
  112. * Third-party database backends can now specify the minimum required version of
  113. the database using the ``DatabaseFeatures.minimum_database_version``
  114. attribute which is a tuple (e.g. ``(10, 0)`` means "10.0"). If a minimum
  115. version is specified, backends must also implement
  116. ``DatabaseWrapper.get_database_version()``, which returns a tuple of the
  117. current database version. The backend's
  118. ``DatabaseWrapper.init_connection_state()`` method must call ``super()`` in
  119. order for the check to run.
  120. Decorators
  121. ~~~~~~~~~~
  122. * ...
  123. Email
  124. ~~~~~
  125. * ...
  126. Error Reporting
  127. ~~~~~~~~~~~~~~~
  128. * ...
  129. File Storage
  130. ~~~~~~~~~~~~
  131. * ...
  132. File Uploads
  133. ~~~~~~~~~~~~
  134. * ...
  135. Forms
  136. ~~~~~
  137. * The new :meth:`~django.forms.BoundField.legend_tag` allows rendering field
  138. labels in ``<legend>`` tags via the new ``tag`` argument of
  139. :meth:`~django.forms.BoundField.label_tag`.
  140. * The new ``edit_only`` argument for :func:`.modelformset_factory` and
  141. :func:`.inlineformset_factory` allows preventing new objects creation.
  142. * The ``js`` and ``css`` class attributes of :doc:`Media </topics/forms/media>`
  143. now allow using hashable objects, not only path strings, as long as those
  144. objects implement the ``__html__()`` method (typically when decorated with
  145. the :func:`~django.utils.html.html_safe` decorator).
  146. Generic Views
  147. ~~~~~~~~~~~~~
  148. * ...
  149. Internationalization
  150. ~~~~~~~~~~~~~~~~~~~~
  151. * The :func:`~django.conf.urls.i18n.i18n_patterns` function now supports
  152. languages with both scripts and regions.
  153. Logging
  154. ~~~~~~~
  155. * ...
  156. Management Commands
  157. ~~~~~~~~~~~~~~~~~~~
  158. * :option:`makemigrations --no-input` now logs default answers and reasons why
  159. migrations cannot be created.
  160. * The new :option:`makemigrations --scriptable` option diverts log output and
  161. input prompts to ``stderr``, writing only paths of generated migration files
  162. to ``stdout``.
  163. * The new :option:`migrate --prune` option allows deleting nonexistent
  164. migrations from the ``django_migrations`` table.
  165. * Python files created by :djadmin:`startproject`, :djadmin:`startapp`,
  166. :djadmin:`optimizemigration`, :djadmin:`makemigrations`, and
  167. :djadmin:`squashmigrations` are now formatted using the ``black`` command if
  168. it is present on your ``PATH``.
  169. * The new :djadmin:`optimizemigration` command allows optimizing operations for
  170. a migration.
  171. Migrations
  172. ~~~~~~~~~~
  173. * ...
  174. Models
  175. ~~~~~~
  176. * The ``order_by`` argument of the
  177. :class:`~django.db.models.expressions.Window` expression now accepts string
  178. references to fields and transforms.
  179. * The new :setting:`CONN_HEALTH_CHECKS` setting allows enabling health checks
  180. for :ref:`persistent database connections <persistent-database-connections>`
  181. in order to reduce the number of failed requests, e.g. after database server
  182. restart.
  183. * :meth:`.QuerySet.bulk_create` now supports updating fields when a row
  184. insertion fails uniqueness constraints. This is supported on MariaDB, MySQL,
  185. PostgreSQL, and SQLite 3.24+.
  186. * :meth:`.QuerySet.iterator` now supports prefetching related objects as long
  187. as the ``chunk_size`` argument is provided. In older versions, no prefetching
  188. was done.
  189. * :class:`~django.db.models.Q` objects and querysets can now be combined using
  190. ``^`` as the exclusive or (``XOR``) operator. ``XOR`` is natively supported
  191. on MariaDB and MySQL. For databases that do not support ``XOR``, the query
  192. will be converted to an equivalent using ``AND``, ``OR``, and ``NOT``.
  193. Requests and Responses
  194. ~~~~~~~~~~~~~~~~~~~~~~
  195. * :meth:`.HttpResponse.set_cookie` now supports :class:`~datetime.timedelta`
  196. objects for the ``max_age`` argument.
  197. Security
  198. ~~~~~~~~
  199. * The new :setting:`SECRET_KEY_FALLBACKS` setting allows providing a list of
  200. values for secret key rotation.
  201. Serialization
  202. ~~~~~~~~~~~~~
  203. * ...
  204. Signals
  205. ~~~~~~~
  206. * The :data:`~django.db.models.signals.pre_delete` and
  207. :data:`~django.db.models.signals.post_delete` signals now dispatch the
  208. ``origin`` of the deletion.
  209. Templates
  210. ~~~~~~~~~
  211. * :tfilter:`json_script` template filter now allows wrapping in a ``<script>``
  212. tag without the HTML ``id`` attribute.
  213. Tests
  214. ~~~~~
  215. * A nested atomic block marked as durable in :class:`django.test.TestCase` now
  216. raises a ``RuntimeError``, the same as outside of tests.
  217. URLs
  218. ~~~~
  219. * ...
  220. Utilities
  221. ~~~~~~~~~
  222. * ``SimpleLazyObject`` now supports addition operations.
  223. * :func:`~django.utils.safestring.mark_safe` now preserves lazy objects.
  224. Validators
  225. ~~~~~~~~~~
  226. * ...
  227. .. _backwards-incompatible-4.1:
  228. Backwards incompatible changes in 4.1
  229. =====================================
  230. Database backend API
  231. --------------------
  232. This section describes changes that may be needed in third-party database
  233. backends.
  234. * ``BaseDatabaseFeatures.has_case_insensitive_like`` is changed from ``True``
  235. to ``False`` to reflect the behavior of most databases.
  236. * ``DatabaseIntrospection.get_key_columns()`` is removed. Use
  237. ``DatabaseIntrospection.get_relations()`` instead.
  238. * ``DatabaseOperations.ignore_conflicts_suffix_sql()`` method is replaced by
  239. ``DatabaseOperations.on_conflict_suffix_sql()`` that accepts the ``fields``,
  240. ``on_conflict``, ``update_fields``, and ``unique_fields`` arguments.
  241. * The ``ignore_conflicts`` argument of the
  242. ``DatabaseOperations.insert_statement()`` method is replaced by
  243. ``on_conflict`` that accepts ``django.db.models.constants.OnConflict``.
  244. :mod:`django.contrib.gis`
  245. -------------------------
  246. * Support for GDAL 2.1 is removed.
  247. Dropped support for MariaDB 10.2
  248. --------------------------------
  249. Upstream support for MariaDB 10.2 ends in May 2022. Django 4.1 supports MariaDB
  250. 10.3 and higher.
  251. Admin changelist searches spanning multi-valued relationships changes
  252. ---------------------------------------------------------------------
  253. Admin changelist searches using multiple search terms are now applied in a
  254. single call to ``filter()``, rather than in sequential ``filter()`` calls.
  255. For multi-valued relationships, this means that rows from the related model
  256. must match all terms rather than any term. For example, if ``search_fields``
  257. is set to ``['child__name', 'child__age']``, and a user searches for
  258. ``'Jamal 17'``, parent rows will be returned only if there is a relationship to
  259. some 17-year-old child named Jamal, rather than also returning parents who
  260. merely have a younger or older child named Jamal in addition to some other
  261. 17-year-old.
  262. See the :ref:`spanning-multi-valued-relationships` topic for more discussion of
  263. this difference. In Django 4.0 and earlier,
  264. :meth:`~django.contrib.admin.ModelAdmin.get_search_results` followed the
  265. second example query, but this undocumented behavior led to queries with
  266. excessive joins.
  267. Reverse foreign key changes for unsaved model instances
  268. -------------------------------------------------------
  269. In order to unify the behavior with many-to-many relations for unsaved model
  270. instances, a reverse foreign key now raises ``ValueError`` when calling
  271. :class:`related managers <django.db.models.fields.related.RelatedManager>` for
  272. unsaved objects.
  273. Miscellaneous
  274. -------------
  275. * Related managers for :class:`~django.db.models.ForeignKey`,
  276. :class:`~django.db.models.ManyToManyField`, and
  277. :class:`~django.contrib.contenttypes.fields.GenericRelation` are now cached
  278. on the :class:`~django.db.models.Model` instance to which they belong.
  279. * The Django test runner now returns a non-zero error code for unexpected
  280. successes from tests marked with :py:func:`unittest.expectedFailure`.
  281. * :class:`~django.middleware.csrf.CsrfViewMiddleware` no longer masks the CSRF
  282. cookie like it does the CSRF token in the DOM.
  283. * :class:`~django.middleware.csrf.CsrfViewMiddleware` now uses
  284. ``request.META['CSRF_COOKIE']`` for storing the unmasked CSRF secret rather
  285. than a masked version. This is an undocumented, private API.
  286. * The :attr:`.ModelAdmin.actions` and
  287. :attr:`~django.contrib.admin.ModelAdmin.inlines` attributes now default to an
  288. empty tuple rather than an empty list to discourage unintended mutation.
  289. * The ``type="text/css"`` attribute is no longer included in ``<link>`` tags
  290. for CSS :doc:`form media </topics/forms/media>`.
  291. * ``formset:added`` and ``formset:removed`` JavaScript events are now pure
  292. JavaScript events and don't depend on jQuery. See
  293. :ref:`admin-javascript-inline-form-events` for more details on the change.
  294. .. _deprecated-features-4.1:
  295. Features deprecated in 4.1
  296. ==========================
  297. Miscellaneous
  298. -------------
  299. * The context for sitemap index templates of a flat list of URLs is deprecated.
  300. Custom sitemap index templates should be updated for the adjusted
  301. :ref:`context variables <sitemap-index-context-variables>`, expecting a list
  302. of objects with ``location`` and optional ``lastmod`` attributes.
  303. * ``CSRF_COOKIE_MASKED`` transitional setting is deprecated.
  304. * The ``name`` argument of :func:`django.utils.functional.cached_property` is
  305. deprecated as it's unnecessary as of Python 3.6.
  306. * The ``opclasses`` argument of
  307. ``django.contrib.postgres.constraints.ExclusionConstraint`` is deprecated in
  308. favor of using :class:`OpClass() <django.contrib.postgres.indexes.OpClass>`
  309. in :attr:`.ExclusionConstraint.expressions`. To use it, you need to add
  310. ``'django.contrib.postgres'`` in your :setting:`INSTALLED_APPS`.
  311. After making this change, :djadmin:`makemigrations` will generate a new
  312. migration with two operations: ``RemoveConstraint`` and ``AddConstraint``.
  313. Since this change has no effect on the database schema,
  314. the :class:`~django.db.migrations.operations.SeparateDatabaseAndState`
  315. operation can be used to only update the migration state without running any
  316. SQL. Move the generated operations into the ``state_operations`` argument of
  317. :class:`~django.db.migrations.operations.SeparateDatabaseAndState`. For
  318. example::
  319. class Migration(migrations.Migration):
  320. ...
  321. operations = [
  322. migrations.SeparateDatabaseAndState(
  323. database_operations=[],
  324. state_operations=[
  325. migrations.RemoveConstraint(
  326. ...
  327. ),
  328. migrations.AddConstraint(
  329. ...
  330. ),
  331. ],
  332. ),
  333. ]
  334. * The undocumented ability to pass ``errors=None`` to
  335. :meth:`.SimpleTestCase.assertFormError` and
  336. :meth:`~.SimpleTestCase.assertFormsetError` is deprecated. Use ``errors=[]``
  337. instead.
  338. * The ``exc_info`` argument of the undocumented
  339. ``django.utils.log.log_response()`` function is replaced by ``exception``.
  340. * ``django.contrib.sessions.serializers.PickleSerializer`` is deprecated due to
  341. the risk of remote code execution.
  342. * The usage of ``QuerySet.iterator()`` on a queryset that prefetches related
  343. objects without providing the ``chunk_size`` argument is deprecated. In older
  344. versions, no prefetching was done. Providing a value for ``chunk_size``
  345. signifies that the additional query per chunk needed to prefetch is desired.
  346. * Passing unsaved model instances to related filters is deprecated. In Django
  347. 5.0, the exception will be raised.
  348. Features removed in 4.1
  349. =======================
  350. These features have reached the end of their deprecation cycle and are removed
  351. in Django 4.1.
  352. See :ref:`deprecated-features-3.2` for details on these changes, including how
  353. to remove usage of these features.
  354. * Support for assigning objects which don't support creating deep copies with
  355. ``copy.deepcopy()`` to class attributes in ``TestCase.setUpTestData()`` is
  356. removed.
  357. * Support for using a boolean value in
  358. :attr:`.BaseCommand.requires_system_checks` is removed.
  359. * The ``whitelist`` argument and ``domain_whitelist`` attribute of
  360. ``django.core.validators.EmailValidator`` are removed.
  361. * The ``default_app_config`` application configuration variable is removed.
  362. * ``TransactionTestCase.assertQuerysetEqual()`` no longer calls ``repr()`` on a
  363. queryset when compared to string values.
  364. * The ``django.core.cache.backends.memcached.MemcachedCache`` backend is
  365. removed.
  366. * Support for the pre-Django 3.2 format of messages used by
  367. ``django.contrib.messages.storage.cookie.CookieStorage`` is removed.