1. ========================
    
  2. Django 4.1 release notes
    
  3. ========================
    
  4. 
    
  5. *August 3, 2022*
    
  6. 
    
  7. Welcome to Django 4.1!
    
  8. 
    
  9. These release notes cover the :ref:`new features <whats-new-4.1>`, as well as
    
  10. some :ref:`backwards incompatible changes <backwards-incompatible-4.1>` you'll
    
  11. want to be aware of when upgrading from Django 4.0 or earlier. We've
    
  12. :ref:`begun the deprecation process for some features
    
  13. <deprecated-features-4.1>`.
    
  14. 
    
  15. See the :doc:`/howto/upgrade-version` guide if you're updating an existing
    
  16. project.
    
  17. 
    
  18. Python compatibility
    
  19. ====================
    
  20. 
    
  21. Django 4.1 supports Python 3.8, 3.9, 3.10, and 3.11 (as of 4.1.3). We
    
  22. **highly recommend** and only officially support the latest release of each
    
  23. series.
    
  24. 
    
  25. .. _whats-new-4.1:
    
  26. 
    
  27. What's new in Django 4.1
    
  28. ========================
    
  29. 
    
  30. Asynchronous handlers for class-based views
    
  31. -------------------------------------------
    
  32. 
    
  33. View subclasses may now define async HTTP method handlers::
    
  34. 
    
  35.     import asyncio
    
  36.     from django.http import HttpResponse
    
  37.     from django.views import View
    
  38. 
    
  39.     class AsyncView(View):
    
  40.         async def get(self, request, *args, **kwargs):
    
  41.             # Perform view logic using await.
    
  42.             await asyncio.sleep(1)
    
  43.             return HttpResponse("Hello async world!")
    
  44. 
    
  45. See :ref:`async-class-based-views` for more details.
    
  46. 
    
  47. Asynchronous ORM interface
    
  48. --------------------------
    
  49. 
    
  50. ``QuerySet`` now provides an asynchronous interface for all data access
    
  51. operations. These are named as-per the existing synchronous operations but with
    
  52. an ``a`` prefix, for example ``acreate()``, ``aget()``, and so on.
    
  53. 
    
  54. The new interface allows you to write asynchronous code without needing to wrap
    
  55. ORM operations in ``sync_to_async()``::
    
  56. 
    
  57.     async for author in Author.objects.filter(name__startswith="A"):
    
  58.         book = await author.books.afirst()
    
  59. 
    
  60. Note that, at this stage, the underlying database operations remain
    
  61. synchronous, with contributions ongoing to push asynchronous support down into
    
  62. the SQL compiler, and integrate asynchronous database drivers. The new
    
  63. asynchronous queryset interface currently encapsulates the necessary
    
  64. ``sync_to_async()`` operations for you, and will allow your code to take
    
  65. advantage of developments in the ORM's asynchronous support as it evolves.
    
  66. 
    
  67. See :ref:`async-queries` for details and limitations.
    
  68. 
    
  69. Validation of Constraints
    
  70. -------------------------
    
  71. 
    
  72. :class:`Check <django.db.models.CheckConstraint>`,
    
  73. :class:`unique <django.db.models.UniqueConstraint>`, and :class:`exclusion
    
  74. <django.contrib.postgres.constraints.ExclusionConstraint>` constraints defined
    
  75. in the :attr:`Meta.constraints <django.db.models.Options.constraints>` option
    
  76. are now checked during :ref:`model validation <validating-objects>`.
    
  77. 
    
  78. Form rendering accessibility
    
  79. ----------------------------
    
  80. 
    
  81. In order to aid users with screen readers, and other assistive technology, new
    
  82. ``<div>`` based form templates are available from this release. These provide
    
  83. more accessible navigation than the older templates, and are able to correctly
    
  84. group related controls, such as radio-lists, into fieldsets.
    
  85. 
    
  86. The new templates are recommended, and will become the default form rendering
    
  87. style when outputting a form, like ``{{ form }}`` in a template, from Django
    
  88. 5.0.
    
  89. 
    
  90. In order to ease adopting the new output style, the default form and formset
    
  91. templates are now configurable at the project level via the
    
  92. :setting:`FORM_RENDERER` setting.
    
  93. 
    
  94. See :ref:`the Forms section (below)<forms-4.1>` for full details.
    
  95. 
    
  96. .. _csrf-cookie-masked-usage:
    
  97. 
    
  98. ``CSRF_COOKIE_MASKED`` setting
    
  99. ------------------------------
    
  100. 
    
  101. The new :setting:`CSRF_COOKIE_MASKED` transitional setting allows specifying
    
  102. whether to mask the CSRF cookie.
    
  103. 
    
  104. :class:`~django.middleware.csrf.CsrfViewMiddleware` no longer masks the CSRF
    
  105. cookie like it does the CSRF token in the DOM. If you are upgrading multiple
    
  106. instances of the same project to Django 4.1, you should set
    
  107. :setting:`CSRF_COOKIE_MASKED` to ``True`` during the transition, in
    
  108. order to allow compatibility with the older versions of Django. Once the
    
  109. transition to 4.1 is complete you can stop overriding
    
  110. :setting:`CSRF_COOKIE_MASKED`.
    
  111. 
    
  112. This setting is deprecated as of this release and will be removed in Django
    
  113. 5.0.
    
  114. 
    
  115. Minor features
    
  116. --------------
    
  117. 
    
  118. :mod:`django.contrib.admin`
    
  119. ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
  120. 
    
  121. * The admin :ref:`dark mode CSS variables <admin-theming>` are now applied in a
    
  122.   separate stylesheet and template block.
    
  123. 
    
  124. * :ref:`modeladmin-list-filters` providing custom ``FieldListFilter``
    
  125.   subclasses can now control the query string value separator when filtering
    
  126.   for multiple values using the ``__in`` lookup.
    
  127. 
    
  128. * The admin :meth:`history view <django.contrib.admin.ModelAdmin.history_view>`
    
  129.   is now paginated.
    
  130. 
    
  131. * Related widget wrappers now have a link to object's change form.
    
  132. 
    
  133. * The :meth:`.AdminSite.get_app_list` method now allows changing the order of
    
  134.   apps and models on the admin index page.
    
  135. 
    
  136. :mod:`django.contrib.auth`
    
  137. ~~~~~~~~~~~~~~~~~~~~~~~~~~
    
  138. 
    
  139. * The default iteration count for the PBKDF2 password hasher is increased from
    
  140.   320,000 to 390,000.
    
  141. 
    
  142. * The :meth:`.RemoteUserBackend.configure_user` method now allows synchronizing
    
  143.   user attributes with attributes in a remote system such as an LDAP directory.
    
  144. 
    
  145. :mod:`django.contrib.gis`
    
  146. ~~~~~~~~~~~~~~~~~~~~~~~~~
    
  147. 
    
  148. * The new :meth:`.GEOSGeometry.make_valid()` method allows converting invalid
    
  149.   geometries to valid ones.
    
  150. 
    
  151. * The new ``clone`` argument for :meth:`.GEOSGeometry.normalize` allows
    
  152.   creating a normalized clone of the geometry.
    
  153. 
    
  154. :mod:`django.contrib.postgres`
    
  155. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
  156. 
    
  157. * The new :class:`BitXor() <django.contrib.postgres.aggregates.BitXor>`
    
  158.   aggregate function returns an ``int`` of the bitwise ``XOR`` of all non-null
    
  159.   input values.
    
  160. 
    
  161. * :class:`~django.contrib.postgres.indexes.SpGistIndex` now supports covering
    
  162.   indexes on PostgreSQL 14+.
    
  163. 
    
  164. * :class:`~django.contrib.postgres.constraints.ExclusionConstraint` now
    
  165.   supports covering exclusion constraints using SP-GiST indexes on PostgreSQL
    
  166.   14+.
    
  167. 
    
  168. * The new ``default_bounds`` attribute of :attr:`DateTimeRangeField
    
  169.   <django.contrib.postgres.fields.DateTimeRangeField.default_bounds>` and
    
  170.   :attr:`DecimalRangeField
    
  171.   <django.contrib.postgres.fields.DecimalRangeField.default_bounds>` allows
    
  172.   specifying bounds for list and tuple inputs.
    
  173. 
    
  174. * :class:`~django.contrib.postgres.constraints.ExclusionConstraint` now allows
    
  175.   specifying operator classes with the
    
  176.   :class:`OpClass() <django.contrib.postgres.indexes.OpClass>` expression.
    
  177. 
    
  178. :mod:`django.contrib.sitemaps`
    
  179. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
  180. 
    
  181. * The default sitemap index template ``<sitemapindex>`` now includes the
    
  182.   ``<lastmod>`` timestamp where available, through the new
    
  183.   :meth:`~django.contrib.sitemaps.Sitemap.get_latest_lastmod` method. Custom
    
  184.   sitemap index templates should be updated for the adjusted :ref:`context
    
  185.   variables <sitemap-index-context-variables>`.
    
  186. 
    
  187. :mod:`django.contrib.staticfiles`
    
  188. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
  189. 
    
  190. * :class:`~django.contrib.staticfiles.storage.ManifestStaticFilesStorage` now
    
  191.   replaces paths to CSS source map references with their hashed counterparts.
    
  192. 
    
  193. Database backends
    
  194. ~~~~~~~~~~~~~~~~~
    
  195. 
    
  196. * Third-party database backends can now specify the minimum required version of
    
  197.   the database using the ``DatabaseFeatures.minimum_database_version``
    
  198.   attribute which is a tuple (e.g. ``(10, 0)`` means "10.0"). If a minimum
    
  199.   version is specified, backends must also implement
    
  200.   ``DatabaseWrapper.get_database_version()``, which returns a tuple of the
    
  201.   current database version. The backend's
    
  202.   ``DatabaseWrapper.init_connection_state()`` method must call ``super()`` in
    
  203.   order for the check to run.
    
  204. 
    
  205. .. _forms-4.1:
    
  206. 
    
  207. Forms
    
  208. ~~~~~
    
  209. 
    
  210. * The default template used to render forms when cast to a string, e.g. in
    
  211.   templates as ``{{ form }}``, is now configurable at the project-level by
    
  212.   setting :attr:`~django.forms.renderers.BaseRenderer.form_template_name` on
    
  213.   the class provided for :setting:`FORM_RENDERER`.
    
  214. 
    
  215.   :attr:`.Form.template_name` is now a property deferring to the renderer, but
    
  216.   may be overridden with a string value to specify the template name per-form
    
  217.   class.
    
  218. 
    
  219.   Similarly, the default template used to render formsets can be specified via
    
  220.   the matching
    
  221.   :attr:`~django.forms.renderers.BaseRenderer.formset_template_name` renderer
    
  222.   attribute.
    
  223. 
    
  224. * The new ``div.html`` form template, referencing
    
  225.   :attr:`.Form.template_name_div` attribute, and matching :meth:`.Form.as_div`
    
  226.   method, render forms using HTML ``<div>`` elements.
    
  227. 
    
  228.   This new output style is recommended over the existing
    
  229.   :meth:`~.Form.as_table`, :meth:`~.Form.as_p` and :meth:`~.Form.as_ul` styles,
    
  230.   as the template implements ``<fieldset>`` and ``<legend>`` to group related
    
  231.   inputs and is easier for screen reader users to navigate.
    
  232. 
    
  233.   The div-based output will become the default rendering style from Django 5.0.
    
  234. 
    
  235. * In order to smooth adoption of the new ``<div>`` output style, two
    
  236.   transitional form renderer classes are available:
    
  237.   :class:`django.forms.renderers.DjangoDivFormRenderer` and
    
  238.   :class:`django.forms.renderers.Jinja2DivFormRenderer`, for the Django and
    
  239.   Jinja2 template backends respectively.
    
  240. 
    
  241.   You can apply one of these via the :setting:`FORM_RENDERER` setting. For
    
  242.   example::
    
  243. 
    
  244.     FORM_RENDERER = "django.forms.renderers.DjangoDivFormRenderer"
    
  245. 
    
  246.   Once the ``<div>`` output style is the default, from Django 5.0, these
    
  247.   transitional renderers will be deprecated, for removal in Django 6.0. The
    
  248.   ``FORM_RENDERER`` declaration can be removed at that time.
    
  249. 
    
  250. * If the new ``<div>`` output style is not appropriate for your project, you should
    
  251.   define a renderer subclass specifying
    
  252.   :attr:`~django.forms.renderers.BaseRenderer.form_template_name` and
    
  253.   :attr:`~django.forms.renderers.BaseRenderer.formset_template_name` for your
    
  254.   required style, and set :setting:`FORM_RENDERER` accordingly.
    
  255. 
    
  256.   For example, for the ``<p>`` output style used by :meth:`~.Form.as_p`, you
    
  257.   would define a form renderer setting ``form_template_name`` to
    
  258.   ``"django/forms/p.html"`` and ``formset_template_name`` to
    
  259.   ``"django/forms/formsets/p.html"``.
    
  260. 
    
  261. * The new :meth:`~django.forms.BoundField.legend_tag` allows rendering field
    
  262.   labels in ``<legend>`` tags via the new ``tag`` argument of
    
  263.   :meth:`~django.forms.BoundField.label_tag`.
    
  264. 
    
  265. * The new ``edit_only`` argument for :func:`.modelformset_factory` and
    
  266.   :func:`.inlineformset_factory` allows preventing new objects creation.
    
  267. 
    
  268. * The ``js`` and ``css`` class attributes of :doc:`Media </topics/forms/media>`
    
  269.   now allow using hashable objects, not only path strings, as long as those
    
  270.   objects implement the ``__html__()`` method (typically when decorated with
    
  271.   the :func:`~django.utils.html.html_safe` decorator).
    
  272. 
    
  273. * The new :attr:`.BoundField.use_fieldset` and :attr:`.Widget.use_fieldset`
    
  274.   attributes help to identify widgets where its inputs should be grouped in a
    
  275.   ``<fieldset>`` with a ``<legend>``.
    
  276. 
    
  277. * The :ref:`formsets-error-messages` argument for
    
  278.   :class:`~django.forms.formsets.BaseFormSet` now allows customizing
    
  279.   error messages for invalid number of forms by passing ``'too_few_forms'``
    
  280.   and ``'too_many_forms'`` keys.
    
  281. 
    
  282. * :class:`~django.forms.IntegerField`, :class:`~django.forms.FloatField`, and
    
  283.   :class:`~django.forms.DecimalField` now optionally accept a ``step_size``
    
  284.   argument. This is used to set the ``step`` HTML attribute, and is validated
    
  285.   on form submission.
    
  286. 
    
  287. Internationalization
    
  288. ~~~~~~~~~~~~~~~~~~~~
    
  289. 
    
  290. * The :func:`~django.conf.urls.i18n.i18n_patterns` function now supports
    
  291.   languages with both scripts and regions.
    
  292. 
    
  293. Management Commands
    
  294. ~~~~~~~~~~~~~~~~~~~
    
  295. 
    
  296. * :option:`makemigrations --no-input` now logs default answers and reasons why
    
  297.   migrations cannot be created.
    
  298. 
    
  299. * The new :option:`makemigrations --scriptable` option diverts log output and
    
  300.   input prompts to ``stderr``, writing only paths of generated migration files
    
  301.   to ``stdout``.
    
  302. 
    
  303. * The new :option:`migrate --prune` option allows deleting nonexistent
    
  304.   migrations from the ``django_migrations`` table.
    
  305. 
    
  306. * Python files created by :djadmin:`startproject`, :djadmin:`startapp`,
    
  307.   :djadmin:`optimizemigration`, :djadmin:`makemigrations`, and
    
  308.   :djadmin:`squashmigrations` are now formatted using the ``black`` command if
    
  309.   it is present on your ``PATH``.
    
  310. 
    
  311. * The new :djadmin:`optimizemigration` command allows optimizing operations for
    
  312.   a migration.
    
  313. 
    
  314. Migrations
    
  315. ~~~~~~~~~~
    
  316. 
    
  317. * The new :class:`~django.db.migrations.operations.RenameIndex` operation
    
  318.   allows renaming indexes defined in the
    
  319.   :attr:`Meta.indexes <django.db.models.Options.indexes>` or
    
  320.   :attr:`~django.db.models.Options.index_together` options.
    
  321. 
    
  322. * The migrations autodetector now generates
    
  323.   :class:`~django.db.migrations.operations.RenameIndex` operations instead of
    
  324.   ``RemoveIndex`` and ``AddIndex``, when renaming indexes defined in the
    
  325.   :attr:`Meta.indexes <django.db.models.Options.indexes>`.
    
  326. 
    
  327. * The migrations autodetector now generates
    
  328.   :class:`~django.db.migrations.operations.RenameIndex` operations instead of
    
  329.   ``AlterIndexTogether`` and ``AddIndex``, when moving indexes defined in the
    
  330.   :attr:`Meta.index_together <django.db.models.Options.index_together>` to the
    
  331.   :attr:`Meta.indexes <django.db.models.Options.indexes>`.
    
  332. 
    
  333. Models
    
  334. ~~~~~~
    
  335. 
    
  336. * The ``order_by`` argument of the
    
  337.   :class:`~django.db.models.expressions.Window` expression now accepts string
    
  338.   references to fields and transforms.
    
  339. 
    
  340. * The new :setting:`CONN_HEALTH_CHECKS` setting allows enabling health checks
    
  341.   for :ref:`persistent database connections <persistent-database-connections>`
    
  342.   in order to reduce the number of failed requests, e.g. after database server
    
  343.   restart.
    
  344. 
    
  345. * :meth:`.QuerySet.bulk_create` now supports updating fields when a row
    
  346.   insertion fails uniqueness constraints. This is supported on MariaDB, MySQL,
    
  347.   PostgreSQL, and SQLite 3.24+.
    
  348. 
    
  349. * :meth:`.QuerySet.iterator` now supports prefetching related objects as long
    
  350.   as the ``chunk_size`` argument is provided. In older versions, no prefetching
    
  351.   was done.
    
  352. 
    
  353. * :class:`~django.db.models.Q` objects and querysets can now be combined using
    
  354.   ``^`` as the exclusive or (``XOR``) operator. ``XOR`` is natively supported
    
  355.   on MariaDB and MySQL. For databases that do not support ``XOR``, the query
    
  356.   will be converted to an equivalent using ``AND``, ``OR``, and ``NOT``.
    
  357. 
    
  358. * The new :ref:`Field.non_db_attrs <custom-field-non_db_attrs>` attribute
    
  359.   allows customizing attributes of fields that don't affect a column
    
  360.   definition.
    
  361. 
    
  362. * On PostgreSQL, ``AutoField``, ``BigAutoField``, and ``SmallAutoField`` are
    
  363.   now created as identity columns rather than serial columns with sequences.
    
  364. 
    
  365. Requests and Responses
    
  366. ~~~~~~~~~~~~~~~~~~~~~~
    
  367. 
    
  368. * :meth:`.HttpResponse.set_cookie` now supports :class:`~datetime.timedelta`
    
  369.   objects for the ``max_age`` argument.
    
  370. 
    
  371. Security
    
  372. ~~~~~~~~
    
  373. 
    
  374. * The new :setting:`SECRET_KEY_FALLBACKS` setting allows providing a list of
    
  375.   values for secret key rotation.
    
  376. 
    
  377. * The :setting:`SECURE_PROXY_SSL_HEADER` setting now supports a comma-separated
    
  378.   list of protocols in the header value.
    
  379. 
    
  380. Signals
    
  381. ~~~~~~~
    
  382. 
    
  383. * The :data:`~django.db.models.signals.pre_delete` and
    
  384.   :data:`~django.db.models.signals.post_delete` signals now dispatch the
    
  385.   ``origin`` of the deletion.
    
  386. 
    
  387. .. _templates-4.1:
    
  388. 
    
  389. Templates
    
  390. ~~~~~~~~~
    
  391. 
    
  392. * The HTML ``<script>`` element ``id`` attribute is no longer required when
    
  393.   wrapping the :tfilter:`json_script` template filter.
    
  394. 
    
  395. * The :class:`cached template loader <django.template.loaders.cached.Loader>`
    
  396.   is now enabled in development, when :setting:`DEBUG` is ``True``, and
    
  397.   :setting:`OPTIONS['loaders'] <TEMPLATES-OPTIONS>` isn't specified. You may
    
  398.   specify ``OPTIONS['loaders']`` to override this, if necessary.
    
  399. 
    
  400. Tests
    
  401. ~~~~~
    
  402. 
    
  403. * The :class:`.DiscoverRunner` now supports running tests in parallel on
    
  404.   macOS, Windows, and any other systems where the default
    
  405.   :mod:`multiprocessing` start method is ``spawn``.
    
  406. 
    
  407. * A nested atomic block marked as durable in :class:`django.test.TestCase` now
    
  408.   raises a ``RuntimeError``, the same as outside of tests.
    
  409. 
    
  410. * :meth:`.SimpleTestCase.assertFormError` and
    
  411.   :meth:`~.SimpleTestCase.assertFormsetError` now support passing a
    
  412.   form/formset object directly.
    
  413. 
    
  414. URLs
    
  415. ~~~~
    
  416. 
    
  417. * The new :attr:`.ResolverMatch.captured_kwargs` attribute stores the captured
    
  418.   keyword arguments, as parsed from the URL.
    
  419. 
    
  420. * The new :attr:`.ResolverMatch.extra_kwargs` attribute stores the additional
    
  421.   keyword arguments passed to the view function.
    
  422. 
    
  423. Utilities
    
  424. ~~~~~~~~~
    
  425. 
    
  426. * ``SimpleLazyObject`` now supports addition operations.
    
  427. 
    
  428. * :func:`~django.utils.safestring.mark_safe` now preserves lazy objects.
    
  429. 
    
  430. Validators
    
  431. ~~~~~~~~~~
    
  432. 
    
  433. * The new :class:`~django.core.validators.StepValueValidator` checks if a value
    
  434.   is an integral multiple of a given step size. This new validator is used for
    
  435.   the new ``step_size`` argument added to form fields representing numeric
    
  436.   values.
    
  437. 
    
  438. .. _backwards-incompatible-4.1:
    
  439. 
    
  440. Backwards incompatible changes in 4.1
    
  441. =====================================
    
  442. 
    
  443. Database backend API
    
  444. --------------------
    
  445. 
    
  446. This section describes changes that may be needed in third-party database
    
  447. backends.
    
  448. 
    
  449. * ``BaseDatabaseFeatures.has_case_insensitive_like`` is changed from ``True``
    
  450.   to ``False`` to reflect the behavior of most databases.
    
  451. 
    
  452. * ``DatabaseIntrospection.get_key_columns()`` is removed. Use
    
  453.   ``DatabaseIntrospection.get_relations()`` instead.
    
  454. 
    
  455. * ``DatabaseOperations.ignore_conflicts_suffix_sql()`` method is replaced by
    
  456.   ``DatabaseOperations.on_conflict_suffix_sql()`` that accepts the ``fields``,
    
  457.   ``on_conflict``, ``update_fields``, and ``unique_fields`` arguments.
    
  458. 
    
  459. * The ``ignore_conflicts`` argument of the
    
  460.   ``DatabaseOperations.insert_statement()`` method is replaced by
    
  461.   ``on_conflict`` that accepts ``django.db.models.constants.OnConflict``.
    
  462. 
    
  463. * ``DatabaseOperations._convert_field_to_tz()`` is replaced by
    
  464.   ``DatabaseOperations._convert_sql_to_tz()`` that accepts the ``sql``,
    
  465.   ``params``, and ``tzname`` arguments.
    
  466. 
    
  467. * Several date and time methods on ``DatabaseOperations`` now take ``sql`` and
    
  468.   ``params`` arguments instead of ``field_name`` and return 2-tuple containing
    
  469.   some SQL and the parameters to be interpolated into that SQL. The changed
    
  470.   methods have these new signatures:
    
  471. 
    
  472.   * ``DatabaseOperations.date_extract_sql(lookup_type, sql, params)``
    
  473.   * ``DatabaseOperations.datetime_extract_sql(lookup_type, sql, params, tzname)``
    
  474.   * ``DatabaseOperations.time_extract_sql(lookup_type, sql, params)``
    
  475.   * ``DatabaseOperations.date_trunc_sql(lookup_type, sql, params, tzname=None)``
    
  476.   * ``DatabaseOperations.datetime_trunc_sql(self, lookup_type, sql, params, tzname)``
    
  477.   * ``DatabaseOperations.time_trunc_sql(lookup_type, sql, params, tzname=None)``
    
  478.   * ``DatabaseOperations.datetime_cast_date_sql(sql, params, tzname)``
    
  479.   * ``DatabaseOperations.datetime_cast_time_sql(sql, params, tzname)``
    
  480. 
    
  481. :mod:`django.contrib.gis`
    
  482. -------------------------
    
  483. 
    
  484. * Support for GDAL 2.1 is removed.
    
  485. 
    
  486. * Support for PostGIS 2.4 is removed.
    
  487. 
    
  488. Dropped support for PostgreSQL 10
    
  489. ---------------------------------
    
  490. 
    
  491. Upstream support for PostgreSQL 10 ends in November 2022. Django 4.1 supports
    
  492. PostgreSQL 11 and higher.
    
  493. 
    
  494. Dropped support for MariaDB 10.2
    
  495. --------------------------------
    
  496. 
    
  497. Upstream support for MariaDB 10.2 ends in May 2022. Django 4.1 supports MariaDB
    
  498. 10.3 and higher.
    
  499. 
    
  500. Admin changelist searches spanning multi-valued relationships changes
    
  501. ---------------------------------------------------------------------
    
  502. 
    
  503. Admin changelist searches using multiple search terms are now applied in a
    
  504. single call to ``filter()``, rather than in sequential ``filter()`` calls.
    
  505. 
    
  506. For multi-valued relationships, this means that rows from the related model
    
  507. must match all terms rather than any term. For example, if ``search_fields``
    
  508. is set to ``['child__name', 'child__age']``, and a user searches for
    
  509. ``'Jamal 17'``, parent rows will be returned only if there is a relationship to
    
  510. some 17-year-old child named Jamal, rather than also returning parents who
    
  511. merely have a younger or older child named Jamal in addition to some other
    
  512. 17-year-old.
    
  513. 
    
  514. See the :ref:`spanning-multi-valued-relationships` topic for more discussion of
    
  515. this difference. In Django 4.0 and earlier,
    
  516. :meth:`~django.contrib.admin.ModelAdmin.get_search_results` followed the
    
  517. second example query, but this undocumented behavior led to queries with
    
  518. excessive joins.
    
  519. 
    
  520. Reverse foreign key changes for unsaved model instances
    
  521. -------------------------------------------------------
    
  522. 
    
  523. In order to unify the behavior with many-to-many relations for unsaved model
    
  524. instances, a reverse foreign key now raises ``ValueError`` when calling
    
  525. :class:`related managers <django.db.models.fields.related.RelatedManager>` for
    
  526. unsaved objects.
    
  527. 
    
  528. Miscellaneous
    
  529. -------------
    
  530. 
    
  531. * Related managers for :class:`~django.db.models.ForeignKey`,
    
  532.   :class:`~django.db.models.ManyToManyField`, and
    
  533.   :class:`~django.contrib.contenttypes.fields.GenericRelation` are now cached
    
  534.   on the :class:`~django.db.models.Model` instance to which they belong. *This
    
  535.   change was reverted in Django 4.1.2.*
    
  536. 
    
  537. * The Django test runner now returns a non-zero error code for unexpected
    
  538.   successes from tests marked with :py:func:`unittest.expectedFailure`.
    
  539. 
    
  540. * :class:`~django.middleware.csrf.CsrfViewMiddleware` no longer masks the CSRF
    
  541.   cookie like it does the CSRF token in the DOM.
    
  542. 
    
  543. * :class:`~django.middleware.csrf.CsrfViewMiddleware` now uses
    
  544.   ``request.META['CSRF_COOKIE']`` for storing the unmasked CSRF secret rather
    
  545.   than a masked version. This is an undocumented, private API.
    
  546. 
    
  547. * The :attr:`.ModelAdmin.actions` and
    
  548.   :attr:`~django.contrib.admin.ModelAdmin.inlines` attributes now default to an
    
  549.   empty tuple rather than an empty list to discourage unintended mutation.
    
  550. 
    
  551. * The ``type="text/css"`` attribute is no longer included in ``<link>`` tags
    
  552.   for CSS :doc:`form media </topics/forms/media>`.
    
  553. 
    
  554. * ``formset:added`` and ``formset:removed`` JavaScript events are now pure
    
  555.   JavaScript events and don't depend on jQuery. See
    
  556.   :ref:`admin-javascript-inline-form-events` for more details on the change.
    
  557. 
    
  558. * The ``exc_info`` argument of the undocumented
    
  559.   ``django.utils.log.log_response()`` function is replaced by ``exception``.
    
  560. 
    
  561. * The ``size`` argument of the undocumented
    
  562.   ``django.views.static.was_modified_since()`` function is removed.
    
  563. 
    
  564. * The admin log out UI now uses ``POST`` requests.
    
  565. 
    
  566. * The undocumented ``InlineAdminFormSet.non_form_errors`` property is replaced
    
  567.   by the ``non_form_errors()`` method. This is consistent with ``BaseFormSet``.
    
  568. 
    
  569. * As per :ref:`above<templates-4.1>`, the cached template loader is now
    
  570.   enabled in development. You may specify ``OPTIONS['loaders']`` to override
    
  571.   this, if necessary.
    
  572. 
    
  573. * The undocumented ``django.contrib.auth.views.SuccessURLAllowedHostsMixin``
    
  574.   mixin is replaced by ``RedirectURLMixin``.
    
  575. 
    
  576. * :class:`~django.db.models.BaseConstraint` subclasses must implement
    
  577.   :meth:`~django.db.models.BaseConstraint.validate` method to allow those
    
  578.   constraints to be used for validation.
    
  579. 
    
  580. * The undocumented ``URLResolver._is_callback()``,
    
  581.   ``URLResolver._callback_strs``, and ``URLPattern.lookup_str()`` are
    
  582.   moved to ``django.contrib.admindocs.utils``.
    
  583. 
    
  584. * The :meth:`.Model.full_clean` method now converts an ``exclude`` value to a
    
  585.   ``set``. It’s also preferable to pass an ``exclude`` value as a ``set`` to
    
  586.   the :meth:`.Model.clean_fields`, :meth:`.Model.full_clean`,
    
  587.   :meth:`.Model.validate_unique`, and :meth:`.Model.validate_constraints`
    
  588.   methods.
    
  589. 
    
  590. * The minimum supported version of ``asgiref`` is increased from 3.4.1 to
    
  591.   3.5.2.
    
  592. 
    
  593. * Combined expressions no longer use the error-prone behavior of guessing
    
  594.   ``output_field`` when argument types match. As a consequence, resolving an
    
  595.   ``output_field`` for database functions and combined expressions may now
    
  596.   crash with mixed types. You will need to explicitly set the ``output_field``
    
  597.   in such cases.
    
  598. 
    
  599. * The :djadmin:`makemessages` command no longer changes ``.po`` files when up
    
  600.   to date. In older versions, ``POT-Creation-Date`` was always updated.
    
  601. 
    
  602. .. _deprecated-features-4.1:
    
  603. 
    
  604. Features deprecated in 4.1
    
  605. ==========================
    
  606. 
    
  607. Log out via GET
    
  608. ---------------
    
  609. 
    
  610. Logging out via ``GET`` requests to the :py:class:`built-in logout view
    
  611. <django.contrib.auth.views.LogoutView>` is deprecated. Use ``POST`` requests
    
  612. instead.
    
  613. 
    
  614. If you want to retain the user experience of an HTML link, you can use a form
    
  615. that is styled to appear as a link:
    
  616. 
    
  617. .. code-block:: html
    
  618. 
    
  619.   <form id="logout-form" method="post" action="{% url 'admin:logout' %}">
    
  620.     {% csrf_token %}
    
  621.     <button type="submit">{% translate "Log out" %}</button>
    
  622.   </form>
    
  623. 
    
  624. .. code-block:: css
    
  625. 
    
  626.   #logout-form {
    
  627.     display: inline;
    
  628.   }
    
  629.   #logout-form button {
    
  630.     background: none;
    
  631.     border: none;
    
  632.     cursor: pointer;
    
  633.     padding: 0;
    
  634.     text-decoration: underline;
    
  635.   }
    
  636. 
    
  637. Miscellaneous
    
  638. -------------
    
  639. 
    
  640. * The context for sitemap index templates of a flat list of URLs is deprecated.
    
  641.   Custom sitemap index templates should be updated for the adjusted
    
  642.   :ref:`context variables <sitemap-index-context-variables>`, expecting a list
    
  643.   of objects with ``location`` and optional ``lastmod`` attributes.
    
  644. 
    
  645. * ``CSRF_COOKIE_MASKED`` transitional setting is deprecated.
    
  646. 
    
  647. * The ``name`` argument of :func:`django.utils.functional.cached_property` is
    
  648.   deprecated as it's unnecessary as of Python 3.6.
    
  649. 
    
  650. * The ``opclasses`` argument of
    
  651.   ``django.contrib.postgres.constraints.ExclusionConstraint`` is deprecated in
    
  652.   favor of using :class:`OpClass() <django.contrib.postgres.indexes.OpClass>`
    
  653.   in :attr:`.ExclusionConstraint.expressions`. To use it, you need to add
    
  654.   ``'django.contrib.postgres'`` in your :setting:`INSTALLED_APPS`.
    
  655. 
    
  656.   After making this change, :djadmin:`makemigrations` will generate a new
    
  657.   migration with two operations: ``RemoveConstraint`` and ``AddConstraint``.
    
  658.   Since this change has no effect on the database schema,
    
  659.   the :class:`~django.db.migrations.operations.SeparateDatabaseAndState`
    
  660.   operation can be used to only update the migration state without running any
    
  661.   SQL. Move the generated operations into the ``state_operations`` argument of
    
  662.   :class:`~django.db.migrations.operations.SeparateDatabaseAndState`. For
    
  663.   example::
    
  664. 
    
  665.     class Migration(migrations.Migration):
    
  666.         ...
    
  667. 
    
  668.         operations = [
    
  669.             migrations.SeparateDatabaseAndState(
    
  670.                 database_operations=[],
    
  671.                 state_operations=[
    
  672.                     migrations.RemoveConstraint(
    
  673.                         ...
    
  674.                     ),
    
  675.                     migrations.AddConstraint(
    
  676.                         ...
    
  677.                     ),
    
  678.                 ],
    
  679.             ),
    
  680.         ]
    
  681. 
    
  682. * The undocumented ability to pass ``errors=None`` to
    
  683.   :meth:`.SimpleTestCase.assertFormError` and
    
  684.   :meth:`~.SimpleTestCase.assertFormsetError` is deprecated. Use ``errors=[]``
    
  685.   instead.
    
  686. 
    
  687. * ``django.contrib.sessions.serializers.PickleSerializer`` is deprecated due to
    
  688.   the risk of remote code execution.
    
  689. 
    
  690. * The usage of ``QuerySet.iterator()`` on a queryset that prefetches related
    
  691.   objects without providing the ``chunk_size`` argument is deprecated. In older
    
  692.   versions, no prefetching was done. Providing a value for ``chunk_size``
    
  693.   signifies that the additional query per chunk needed to prefetch is desired.
    
  694. 
    
  695. * Passing unsaved model instances to related filters is deprecated. In Django
    
  696.   5.0, the exception will be raised.
    
  697. 
    
  698. * ``created=True`` is added to the signature of
    
  699.   :meth:`.RemoteUserBackend.configure_user`. Support  for ``RemoteUserBackend``
    
  700.   subclasses that do not accept this argument is deprecated.
    
  701. 
    
  702. * The :data:`django.utils.timezone.utc` alias to :attr:`datetime.timezone.utc`
    
  703.   is deprecated. Use :attr:`datetime.timezone.utc` directly.
    
  704. 
    
  705. * Passing a response object and a form/formset name to
    
  706.   ``SimpleTestCase.assertFormError()`` and ``assertFormsetError()`` is
    
  707.   deprecated. Use::
    
  708. 
    
  709.     assertFormError(response.context['form_name'], …)
    
  710.     assertFormsetError(response.context['formset_name'], …)
    
  711. 
    
  712.   or pass the form/formset object directly instead.
    
  713. 
    
  714. * The undocumented ``django.contrib.gis.admin.OpenLayersWidget`` is deprecated.
    
  715. 
    
  716. * ``django.contrib.auth.hashers.CryptPasswordHasher`` is deprecated.
    
  717. 
    
  718. * The ability to pass ``nulls_first=False`` or ``nulls_last=False`` to
    
  719.   ``Expression.asc()`` and ``Expression.desc()`` methods, and the ``OrderBy``
    
  720.   expression is deprecated. Use ``None`` instead.
    
  721. 
    
  722. * The ``"django/forms/default.html"`` and
    
  723.   ``"django/forms/formsets/default.html"`` templates which are a proxy to the
    
  724.   table-based templates are deprecated. Use the specific template instead.
    
  725. 
    
  726. * The undocumented ``LogoutView.get_next_page()`` method is renamed to
    
  727.   ``get_success_url()``.
    
  728. 
    
  729. Features removed in 4.1
    
  730. =======================
    
  731. 
    
  732. These features have reached the end of their deprecation cycle and are removed
    
  733. in Django 4.1.
    
  734. 
    
  735. See :ref:`deprecated-features-3.2` for details on these changes, including how
    
  736. to remove usage of these features.
    
  737. 
    
  738. * Support for assigning objects which don't support creating deep copies with
    
  739.   ``copy.deepcopy()`` to class attributes in ``TestCase.setUpTestData()`` is
    
  740.   removed.
    
  741. 
    
  742. * Support for using a boolean value in
    
  743.   :attr:`.BaseCommand.requires_system_checks` is removed.
    
  744. 
    
  745. * The ``whitelist`` argument and ``domain_whitelist`` attribute of
    
  746.   ``django.core.validators.EmailValidator`` are removed.
    
  747. 
    
  748. * The ``default_app_config`` application configuration variable is removed.
    
  749. 
    
  750. * ``TransactionTestCase.assertQuerysetEqual()`` no longer calls ``repr()`` on a
    
  751.   queryset when compared to string values.
    
  752. 
    
  753. * The ``django.core.cache.backends.memcached.MemcachedCache`` backend is
    
  754.   removed.
    
  755. 
    
  756. * Support for the pre-Django 3.2 format of messages used by
    
  757.   ``django.contrib.messages.storage.cookie.CookieStorage`` is removed.