4.1.txt 25 KB

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