4.1.txt 20 KB

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