From 9334499f537e402ce5b92708209933045a8c5e7d Mon Sep 17 00:00:00 2001 From: Jacob Walls Date: Wed, 17 Sep 2025 09:21:40 -0400 Subject: [PATCH 1/5] Refs #35859 -- Included Task backends in system checks docs. --- docs/topics/checks.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/topics/checks.txt b/docs/topics/checks.txt index 626f40a3b11b..e22415e6d6ff 100644 --- a/docs/topics/checks.txt +++ b/docs/topics/checks.txt @@ -131,18 +131,18 @@ The code below is equivalent to the code above:: .. _field-checking: -Field, constraint, model, manager, template engine, and database checks ------------------------------------------------------------------------ +Field, constraint, model, manager, template engine, task, and database checks +----------------------------------------------------------------------------- In some cases, you won't need to register your check function -- you can piggyback on an existing registration. -Fields, constraints, models, model managers, template engines, and database -backends all implement a ``check()`` method that is already registered with the -check framework. If you want to add extra checks, you can extend the -implementation on the base class, perform any extra checks you need, and append -any messages to those generated by the base class. It's recommended that you -delegate each check to separate methods. +Fields, constraints, models, model managers, template engines, task backends, +and database backends all implement a ``check()`` method that is already +registered with the check framework. If you want to add extra checks, you can +extend the implementation on the base class, perform any extra checks you need, +and append any messages to those generated by the base class. It's recommended +that you delegate each check to separate methods. Consider an example where you are implementing a custom field named ``RangedIntegerField``. This field adds ``min`` and ``max`` arguments to the From b931156c207f661406635d49e0e29a51cacc1ab8 Mon Sep 17 00:00:00 2001 From: Jacob Walls Date: Wed, 17 Sep 2025 09:19:25 -0400 Subject: [PATCH 2/5] Refs #35859 -- Removed support for Task enqueuing on transaction commit. This removes the ability to configure Task enqueueing via a setting, since the proposed `ENQUEUE_ON_COMMIT` did not support multi-database setups. Thanks to Simon Charette for the report. Follow-up to 4289966d1b8e848e5e460b7c782dac009d746b20. --- django/tasks/backends/base.py | 28 +----- django/tasks/backends/dummy.py | 7 +- django/tasks/backends/immediate.py | 7 +- django/tasks/base.py | 6 -- docs/ref/checks.txt | 8 -- docs/ref/settings.txt | 14 --- docs/ref/signals.txt | 4 +- docs/ref/tasks.txt | 15 +-- docs/topics/tasks.txt | 47 ++++----- tests/tasks/tasks.py | 10 -- tests/tasks/test_custom_backend.py | 1 - tests/tasks/test_dummy_backend.py | 134 +------------------------- tests/tasks/test_immediate_backend.py | 94 +----------------- tests/tasks/test_tasks.py | 2 - 14 files changed, 29 insertions(+), 348 deletions(-) diff --git a/django/tasks/backends/base.py b/django/tasks/backends/base.py index 32ae10018de3..938e36f21ed9 100644 --- a/django/tasks/backends/base.py +++ b/django/tasks/backends/base.py @@ -4,8 +4,6 @@ from asgiref.sync import sync_to_async from django.conf import settings -from django.core import checks -from django.db import connections from django.tasks import DEFAULT_TASK_QUEUE_NAME from django.tasks.base import ( DEFAULT_TASK_PRIORITY, @@ -39,16 +37,8 @@ class BaseTaskBackend(metaclass=ABCMeta): def __init__(self, alias, params): self.alias = alias self.queues = set(params.get("QUEUES", [DEFAULT_TASK_QUEUE_NAME])) - self.enqueue_on_commit = bool(params.get("ENQUEUE_ON_COMMIT", True)) self.options = params.get("OPTIONS", {}) - def _get_enqueue_on_commit_for_task(self, task): - return ( - task.enqueue_on_commit - if task.enqueue_on_commit is not None - else self.enqueue_on_commit - ) - def validate_task(self, task): """ Determine whether the provided Task can be executed by the backend. @@ -119,20 +109,4 @@ async def aget_result(self, result_id): ) def check(self, **kwargs): - if self.enqueue_on_commit and not connections._settings: - yield checks.Error( - "ENQUEUE_ON_COMMIT cannot be used when no databases are configured.", - hint="Set ENQUEUE_ON_COMMIT to False", - id="tasks.E001", - ) - - elif ( - self.enqueue_on_commit - and not connections["default"].features.supports_transactions - ): - yield checks.Error( - "ENQUEUE_ON_COMMIT cannot be used on a database which doesn't support " - "transactions.", - hint="Set ENQUEUE_ON_COMMIT to False", - id="tasks.E002", - ) + return [] diff --git a/django/tasks/backends/dummy.py b/django/tasks/backends/dummy.py index 93bb8f3ee4fa..bc7060ccc475 100644 --- a/django/tasks/backends/dummy.py +++ b/django/tasks/backends/dummy.py @@ -1,7 +1,5 @@ from copy import deepcopy -from functools import partial -from django.db import transaction from django.tasks.base import TaskResult, TaskResultStatus from django.tasks.exceptions import TaskResultDoesNotExist from django.tasks.signals import task_enqueued @@ -43,10 +41,7 @@ def enqueue(self, task, args, kwargs): worker_ids=[], ) - if self._get_enqueue_on_commit_for_task(task) is not False: - transaction.on_commit(partial(self._store_result, result)) - else: - self._store_result(result) + self._store_result(result) # Copy the task to prevent mutation issues. return deepcopy(result) diff --git a/django/tasks/backends/immediate.py b/django/tasks/backends/immediate.py index 06b94d18ab2d..2e154850aa2c 100644 --- a/django/tasks/backends/immediate.py +++ b/django/tasks/backends/immediate.py @@ -1,8 +1,6 @@ import logging -from functools import partial from traceback import format_exception -from django.db import transaction from django.tasks.base import TaskContext, TaskError, TaskResult, TaskResultStatus from django.tasks.signals import task_enqueued, task_finished, task_started from django.utils import timezone @@ -92,9 +90,6 @@ def enqueue(self, task, args, kwargs): worker_ids=[], ) - if self._get_enqueue_on_commit_for_task(task) is not False: - transaction.on_commit(partial(self._execute_task, task_result)) - else: - self._execute_task(task_result) + self._execute_task(task_result) return task_result diff --git a/django/tasks/base.py b/django/tasks/base.py index 905dbef597b4..cffcdd899647 100644 --- a/django/tasks/base.py +++ b/django/tasks/base.py @@ -48,10 +48,6 @@ class Task: queue_name: str run_after: Optional[datetime] # The earliest this Task will run. - # Whether the Task will be enqueued when the current transaction commits, - # immediately, or whatever the backend decides. - enqueue_on_commit: Optional[bool] - # Whether the Task receives the Task context when executed. takes_context: bool = False @@ -140,7 +136,6 @@ def task( priority=DEFAULT_TASK_PRIORITY, queue_name=DEFAULT_TASK_QUEUE_NAME, backend=DEFAULT_TASK_BACKEND_ALIAS, - enqueue_on_commit=None, takes_context=False, ): from . import task_backends @@ -151,7 +146,6 @@ def wrapper(f): func=f, queue_name=queue_name, backend=backend, - enqueue_on_commit=enqueue_on_commit, takes_context=takes_context, run_after=None, ) diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt index 138db8708e2c..e1ea5bc7537d 100644 --- a/docs/ref/checks.txt +++ b/docs/ref/checks.txt @@ -597,14 +597,6 @@ Signals a lazy reference to the sender ``.``, but app ```` isn't installed or doesn't provide model ````. -Tasks ------ - -* **tasks.E001**: ``ENQUEUE_ON_COMMIT`` cannot be used when no databases are - configured. -* **tasks.E002**: ``ENQUEUE_ON_COMMIT`` cannot be used on a database which - doesn't support transactions. - Templates --------- diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt index 54957a726a63..b0750d3a42de 100644 --- a/docs/ref/settings.txt +++ b/docs/ref/settings.txt @@ -2806,20 +2806,6 @@ You can use a backend that doesn't ship with Django by setting :setting:`BACKEND ` to a fully-qualified path of a backend class (i.e. ``mypackage.backends.whatever.WhateverBackend``). -.. setting:: TASKS-ENQUEUE_ON_COMMIT - -``ENQUEUE_ON_COMMIT`` -~~~~~~~~~~~~~~~~~~~~~ - -Default: ``True`` - -Whether to enqueue a Task only after the current transaction, if any, commits -successfully, instead of enqueueing immediately. - -This can also be configured on a per-Task basis. - -See :ref:`Task transactions ` for more information. - .. setting:: TASKS-QUEUES ``QUEUES`` diff --git a/docs/ref/signals.txt b/docs/ref/signals.txt index 82b92e12c2cc..44958dcef3e8 100644 --- a/docs/ref/signals.txt +++ b/docs/ref/signals.txt @@ -717,9 +717,7 @@ Signals sent by the :doc:`tasks ` framework. .. data:: django.tasks.signals.task_enqueued :module: -Sent once a Task has been enqueued. If -:attr:`django.tasks.Task.enqueue_on_commit` is set, the signal is only sent -once the transaction commits successfully. +Sent once a Task has been enqueued. Arguments sent with this signal: diff --git a/docs/ref/tasks.txt b/docs/ref/tasks.txt index 3134243d409a..c427c4c4d33f 100644 --- a/docs/ref/tasks.txt +++ b/docs/ref/tasks.txt @@ -13,7 +13,7 @@ Task definition The ``task`` decorator ---------------------- -.. function:: task(*, priority=0, queue_name="default", backend="default", enqueue_on_commit=None, takes_context=False) +.. function:: task(*, priority=0, queue_name="default", backend="default", takes_context=False) The ``@task`` decorator defines a :class:`Task` instance. This has the following optional arguments: @@ -24,8 +24,6 @@ The ``task`` decorator Defaults to ``"default"``. * ``backend``: Sets the :attr:`~Task.backend` of the ``Task``. Defaults to ``"default"``. - * ``enqueue_on_commit``: Sets :attr:`~Task.enqueue_on_commit` for the - ``Task``. Defaults to ``None``. * ``takes_context``: Controls whether the ``Task`` function accepts a :class:`TaskContext`. Defaults to ``False``. See :ref:`Task context ` for details. @@ -77,14 +75,6 @@ The ``task`` decorator this feature. Otherwise, :exc:`~django.tasks.exceptions.InvalidTask` is raised. - .. attribute:: Task.enqueue_on_commit - - Whether the ``Task`` should be enqueued when the transaction commits - successfully, or immediately. Defaults to :setting:`ENQUEUE_ON_COMMIT - ` for the backend. - - See :ref:`Task transactions ` for more information. - .. attribute:: Task.name The name of the function decorated with :func:`task`. This name is not @@ -210,9 +200,6 @@ Task results The time when the ``Task`` was enqueued. - If :attr:`Task.enqueue_on_commit` was set, this is the time the - transaction committed. - .. attribute:: TaskResult.started_at The time when the ``Task`` began execution, on its first attempt. diff --git a/docs/topics/tasks.txt b/docs/topics/tasks.txt index 17c233d5955a..13afd8b09f6c 100644 --- a/docs/topics/tasks.txt +++ b/docs/topics/tasks.txt @@ -67,13 +67,6 @@ To use it, set :setting:`BACKEND ` to The :class:`.ImmediateBackend` may also be useful in tests, to bypass the need to run a real background worker in your tests. -.. admonition:: ``ImmediateBackend`` and ``ENQUEUE_ON_COMMIT`` - - When :setting:`ENQUEUE_ON_COMMIT ` is ``False``, - the Task will be executed within the same transaction it was enqueued in. - - See :ref:`Task transactions ` for more information. - .. _dummy-task-backend: Dummy backend @@ -182,7 +175,7 @@ decorator arguments:: from django.tasks import task - @task(priority=2, queue_name="emails", enqueue_on_commit=True) + @task(priority=2, queue_name="emails") def email_users(emails, subject, message): return send_mail( subject=subject, message=message, from_email=None, recipient_list=emails @@ -304,33 +297,35 @@ conversion. Transactions ------------ -By default, Tasks are enqueued after the current database transaction (if there -is one) commits successfully (using :meth:`transaction.on_commit() -`), rather than enqueueing immediately. For -most backends, Tasks are run in a separate process, using a different database -connection. Without waiting for the transaction to commit, workers could start -to process a Task which uses objects it can't access yet. - -This behavior can be changed by changing the :setting:`TASKS-ENQUEUE_ON_COMMIT` -setting for the backend, or for a specific Task using the ``enqueue_on_commit`` -parameter. +For most backends, Tasks are run in a separate process, using a different +database connection. When using a transaction, without waiting for it to +commit, workers could start to process a Task which uses objects it can't +access yet. For example, consider this simplified example:: @task - def my_task(): - Thing.objects.get() + def my_task(thing_num): + Thing.objects.get(num=thing_num) with transaction.atomic(): - Thing.objects.create() - my_task.enqueue() + Thing.objects.create(num=1) + my_task.enqueue(thing_num=1) +To prevent the scenario where ``my_task`` runs before the ``Thing`` is +committed to the database, use :func:`transaction.on_commit() +`, binding all arguments to +:meth:`~django.tasks.Task.enqueue` via :func:`functools.partial`:: -If :setting:`ENQUEUE_ON_COMMIT ` is ``False``, then it -is possible for ``my_task`` to run before the ``Thing`` is committed to the -database, and the Task won't be able to see the created object within your -transaction. + from functools import partial + + from django.db import transaction + + + with transaction.atomic(): + Thing.objects.create(num=1) + transaction.on_commit(partial(my_task.enqueue, thing_num=1)) .. _task-results: diff --git a/tests/tasks/tasks.py b/tests/tasks/tasks.py index 3959660ab91e..ede585dc5fdd 100644 --- a/tests/tasks/tasks.py +++ b/tests/tasks/tasks.py @@ -54,16 +54,6 @@ def exit_task(): exit(1) -@task(enqueue_on_commit=True) -def enqueue_on_commit_task(): - pass - - -@task(enqueue_on_commit=False) -def never_enqueue_on_commit_task(): - pass - - @task() def hang(): """ diff --git a/tests/tasks/test_custom_backend.py b/tests/tasks/test_custom_backend.py index 83a302a18372..c8508d5d3b23 100644 --- a/tests/tasks/test_custom_backend.py +++ b/tests/tasks/test_custom_backend.py @@ -27,7 +27,6 @@ class CustomBackendNoEnqueue(BaseTaskBackend): TASKS={ "default": { "BACKEND": f"{CustomBackend.__module__}.{CustomBackend.__qualname__}", - "ENQUEUE_ON_COMMIT": False, "OPTIONS": {"prefix": "PREFIX: "}, }, "no_enqueue": { diff --git a/tests/tasks/test_dummy_backend.py b/tests/tasks/test_dummy_backend.py index 27205f6ab3e3..18064adfba48 100644 --- a/tests/tasks/test_dummy_backend.py +++ b/tests/tasks/test_dummy_backend.py @@ -2,17 +2,11 @@ from unittest import mock from django.db import transaction -from django.db.utils import ConnectionHandler from django.tasks import TaskResultStatus, default_task_backend, task_backends from django.tasks.backends.dummy import DummyBackend from django.tasks.base import Task from django.tasks.exceptions import InvalidTask, TaskResultDoesNotExist -from django.test import ( - SimpleTestCase, - TransactionTestCase, - override_settings, - skipIfDBFeature, -) +from django.test import SimpleTestCase, TransactionTestCase, override_settings from . import tasks as test_tasks @@ -22,7 +16,6 @@ "default": { "BACKEND": "django.tasks.backends.dummy.DummyBackend", "QUEUES": [], - "ENQUEUE_ON_COMMIT": False, } } ) @@ -119,14 +112,6 @@ async def test_get_missing_result(self): with self.assertRaises(TaskResultDoesNotExist): await default_task_backend.aget_result("123") - def test_enqueue_on_commit(self): - self.assertIs( - default_task_backend._get_enqueue_on_commit_for_task( - test_tasks.enqueue_on_commit_task - ), - True, - ) - def test_enqueue_logs(self): with self.assertLogs("django.tasks", level="DEBUG") as captured_logs: result = test_tasks.noop_task.enqueue() @@ -150,20 +135,6 @@ def test_check(self): errors = list(default_task_backend.check()) self.assertEqual(len(errors), 0, errors) - @override_settings( - TASKS={ - "default": { - "BACKEND": "django.tasks.backends.dummy.DummyBackend", - "ENQUEUE_ON_COMMIT": True, - } - } - ) - @mock.patch("django.tasks.backends.base.connections", ConnectionHandler({})) - def test_enqueue_on_commit_with_no_databases(self): - self.assertIn( - "tasks.E001", {error.id for error in default_task_backend.check()} - ) - def test_takes_context(self): result = test_tasks.get_task_id.enqueue() self.assertEqual(result.status, TaskResultStatus.READY) @@ -188,7 +159,6 @@ def test_validate_on_enqueue(self): "default": { "BACKEND": "django.tasks.backends.dummy.DummyBackend", "QUEUES": ["queue-1"], - "ENQUEUE_ON_COMMIT": False, } } ): @@ -207,7 +177,6 @@ async def test_validate_on_aenqueue(self): "default": { "BACKEND": "django.tasks.backends.dummy.DummyBackend", "QUEUES": ["queue-1"], - "ENQUEUE_ON_COMMIT": False, } } ): @@ -224,39 +193,10 @@ class DummyBackendTransactionTestCase(TransactionTestCase): TASKS={ "default": { "BACKEND": "django.tasks.backends.dummy.DummyBackend", - "ENQUEUE_ON_COMMIT": True, } } ) - def test_wait_until_transaction_commit(self): - self.assertIs(default_task_backend.enqueue_on_commit, True) - self.assertIs( - default_task_backend._get_enqueue_on_commit_for_task(test_tasks.noop_task), - True, - ) - - with transaction.atomic(): - test_tasks.noop_task.enqueue() - - self.assertEqual(len(default_task_backend.results), 0) - - self.assertEqual(len(default_task_backend.results), 1) - - @override_settings( - TASKS={ - "default": { - "BACKEND": "django.tasks.backends.dummy.DummyBackend", - "ENQUEUE_ON_COMMIT": False, - } - } - ) - def test_doesnt_wait_until_transaction_commit(self): - self.assertIs(default_task_backend.enqueue_on_commit, False) - self.assertIs( - default_task_backend._get_enqueue_on_commit_for_task(test_tasks.noop_task), - False, - ) - + def test_doesnt_wait_until_transaction_commit_by_default(self): with transaction.atomic(): result = test_tasks.noop_task.enqueue() @@ -265,73 +205,3 @@ def test_doesnt_wait_until_transaction_commit(self): self.assertEqual(len(default_task_backend.results), 1) self.assertEqual(len(default_task_backend.results), 1) - - @override_settings( - TASKS={ - "default": { - "BACKEND": "django.tasks.backends.dummy.DummyBackend", - } - } - ) - def test_wait_until_transaction_by_default(self): - self.assertIs(default_task_backend.enqueue_on_commit, True) - self.assertIs( - default_task_backend._get_enqueue_on_commit_for_task(test_tasks.noop_task), - True, - ) - - with transaction.atomic(): - result = test_tasks.noop_task.enqueue() - - self.assertIsNone(result.enqueued_at) - - self.assertEqual(len(default_task_backend.results), 0) - - self.assertEqual(len(default_task_backend.results), 1) - self.assertIsNone(result.enqueued_at) - result.refresh() - self.assertIsNotNone(result.enqueued_at) - - @override_settings( - TASKS={ - "default": { - "BACKEND": "django.tasks.backends.dummy.DummyBackend", - "ENQUEUE_ON_COMMIT": False, - } - } - ) - def test_task_specific_enqueue_on_commit(self): - self.assertIs(default_task_backend.enqueue_on_commit, False) - self.assertIs(test_tasks.enqueue_on_commit_task.enqueue_on_commit, True) - self.assertIs( - default_task_backend._get_enqueue_on_commit_for_task( - test_tasks.enqueue_on_commit_task - ), - True, - ) - - with transaction.atomic(): - result = test_tasks.enqueue_on_commit_task.enqueue() - - self.assertIsNone(result.enqueued_at) - - self.assertEqual(len(default_task_backend.results), 0) - - self.assertEqual(len(default_task_backend.results), 1) - self.assertIsNone(result.enqueued_at) - result.refresh() - self.assertIsNotNone(result.enqueued_at) - - @override_settings( - TASKS={ - "default": { - "BACKEND": "django.tasks.backends.dummy.DummyBackend", - "ENQUEUE_ON_COMMIT": True, - } - } - ) - @skipIfDBFeature("supports_transactions") - def test_enqueue_on_commit_with_no_transactions(self): - self.assertIn( - "tasks.E002", {error.id for error in default_task_backend.check()} - ) diff --git a/tests/tasks/test_immediate_backend.py b/tests/tasks/test_immediate_backend.py index 01e2841aa7db..356e9ab2649d 100644 --- a/tests/tasks/test_immediate_backend.py +++ b/tests/tasks/test_immediate_backend.py @@ -13,7 +13,6 @@ "default": { "BACKEND": "django.tasks.backends.immediate.ImmediateBackend", "QUEUES": [], - "ENQUEUE_ON_COMMIT": False, } } ) @@ -203,14 +202,6 @@ def test_cannot_pass_run_after(self): test_tasks.failing_task_value_error.using(run_after=timezone.now()) ) - def test_enqueue_on_commit(self): - self.assertIs( - default_task_backend._get_enqueue_on_commit_for_task( - test_tasks.enqueue_on_commit_task - ), - True, - ) - def test_enqueue_logs(self): with self.assertLogs("django.tasks", level="DEBUG") as captured_logs: result = test_tasks.noop_task.enqueue() @@ -256,7 +247,6 @@ def test_validate_on_enqueue(self): "default": { "BACKEND": "django.tasks.backends.immediate.ImmediateBackend", "QUEUES": ["queue-1"], - "ENQUEUE_ON_COMMIT": False, } } ): @@ -275,7 +265,6 @@ async def test_validate_on_aenqueue(self): "default": { "BACKEND": "django.tasks.backends.immediate.ImmediateBackend", "QUEUES": ["queue-1"], - "ENQUEUE_ON_COMMIT": False, } } ): @@ -292,43 +281,10 @@ class ImmediateBackendTransactionTestCase(TransactionTestCase): TASKS={ "default": { "BACKEND": "django.tasks.backends.immediate.ImmediateBackend", - "ENQUEUE_ON_COMMIT": True, } } ) - def test_wait_until_transaction_commit(self): - self.assertIs(default_task_backend.enqueue_on_commit, True) - self.assertIs( - default_task_backend._get_enqueue_on_commit_for_task(test_tasks.noop_task), - True, - ) - - with transaction.atomic(): - result = test_tasks.noop_task.enqueue() - - self.assertIsNone(result.enqueued_at) - self.assertEqual(result.attempts, 0) - self.assertEqual(result.status, TaskResultStatus.READY) - - self.assertEqual(result.status, TaskResultStatus.SUCCESSFUL) - self.assertIsNotNone(result.enqueued_at) - self.assertEqual(result.attempts, 1) - - @override_settings( - TASKS={ - "default": { - "BACKEND": "django.tasks.backends.immediate.ImmediateBackend", - "ENQUEUE_ON_COMMIT": False, - } - } - ) - def test_doesnt_wait_until_transaction_commit(self): - self.assertIs(default_task_backend.enqueue_on_commit, False) - self.assertIs( - default_task_backend._get_enqueue_on_commit_for_task(test_tasks.noop_task), - False, - ) - + def test_doesnt_wait_until_transaction_commit_by_default(self): with transaction.atomic(): result = test_tasks.noop_task.enqueue() @@ -337,51 +293,3 @@ def test_doesnt_wait_until_transaction_commit(self): self.assertEqual(result.status, TaskResultStatus.SUCCESSFUL) self.assertEqual(result.status, TaskResultStatus.SUCCESSFUL) - - @override_settings( - TASKS={ - "default": { - "BACKEND": "django.tasks.backends.immediate.ImmediateBackend", - } - } - ) - def test_wait_until_transaction_by_default(self): - self.assertIs(default_task_backend.enqueue_on_commit, True) - self.assertIs( - default_task_backend._get_enqueue_on_commit_for_task(test_tasks.noop_task), - True, - ) - - with transaction.atomic(): - result = test_tasks.noop_task.enqueue() - - self.assertIsNone(result.enqueued_at) - self.assertEqual(result.status, TaskResultStatus.READY) - - self.assertEqual(result.status, TaskResultStatus.SUCCESSFUL) - - @override_settings( - TASKS={ - "default": { - "BACKEND": "django.tasks.backends.immediate.ImmediateBackend", - "ENQUEUE_ON_COMMIT": False, - } - } - ) - def test_task_specific_enqueue_on_commit(self): - self.assertIs(default_task_backend.enqueue_on_commit, False) - self.assertIs(test_tasks.enqueue_on_commit_task.enqueue_on_commit, True) - self.assertIs( - default_task_backend._get_enqueue_on_commit_for_task( - test_tasks.enqueue_on_commit_task - ), - True, - ) - - with transaction.atomic(): - result = test_tasks.enqueue_on_commit_task.enqueue() - - self.assertIsNone(result.enqueued_at) - self.assertEqual(result.status, TaskResultStatus.READY) - - self.assertEqual(result.status, TaskResultStatus.SUCCESSFUL) diff --git a/tests/tasks/test_tasks.py b/tests/tasks/test_tasks.py index 2c11d9657d50..14d47c4cf625 100644 --- a/tests/tasks/test_tasks.py +++ b/tests/tasks/test_tasks.py @@ -29,11 +29,9 @@ "default": { "BACKEND": "django.tasks.backends.dummy.DummyBackend", "QUEUES": ["default", "queue_1"], - "ENQUEUE_ON_COMMIT": False, }, "immediate": { "BACKEND": "django.tasks.backends.immediate.ImmediateBackend", - "ENQUEUE_ON_COMMIT": False, "QUEUES": [], }, "missing": {"BACKEND": "does.not.exist"}, From 4e1aebffdd829e278343d7334cc79ed89d55d2ad Mon Sep 17 00:00:00 2001 From: Natalia <124304+nessita@users.noreply.github.com> Date: Tue, 16 Sep 2025 23:09:11 -0300 Subject: [PATCH 3/5] Updated man page for Django 6.0 alpha 1. --- docs/man/django-admin.1 | 148 ++++++++++++++++++++++++++-------------- 1 file changed, 95 insertions(+), 53 deletions(-) diff --git a/docs/man/django-admin.1 b/docs/man/django-admin.1 index 67c4855e6378..b8c61b1078d7 100644 --- a/docs/man/django-admin.1 +++ b/docs/man/django-admin.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "DJANGO-ADMIN" "1" "January 15, 2025" "5.2" "Django" +.TH "DJANGO-ADMIN" "1" "September 17, 2025" "6.0" "Django" .SH NAME django-admin \- Utility script for the Django web framework .sp @@ -83,8 +83,8 @@ Run \fBdjango\-admin help \fP to display a description of the given command and a list of its available options. .SS App names .sp -Many commands take a list of \(dqapp names.\(dq An \(dqapp name\(dq is the basename of -the package containing your models. For example, if your \fI\%INSTALLED_APPS\fP +Many commands take a list of \(dqapp names.\(dq An \(dqapp name\(dq is the basename of the +package containing your models. For example, if your \fI\%INSTALLED_APPS\fP contains the string \fB\(aqmysite.blog\(aq\fP, the app name is \fBblog\fP\&. .SS Determining the version .INDENT 0.0 @@ -173,13 +173,14 @@ Lists all available tags. .B \-\-deploy .UNINDENT .sp -Activates some additional checks that are only relevant in a deployment setting. +Activates some additional checks that are only relevant in a deployment +setting. .sp You can use this option in your local development environment, but since your -local development settings module may not have many of your production settings, -you will probably want to point the \fBcheck\fP command at a different settings -module, either by setting the \fI\%DJANGO_SETTINGS_MODULE\fP environment -variable, or by passing the \fB\-\-settings\fP option: +local development settings module may not have many of your production +settings, you will probably want to point the \fBcheck\fP command at a different +settings module, either by setting the \fI\%DJANGO_SETTINGS_MODULE\fP +environment variable, or by passing the \fB\-\-settings\fP option: .INDENT 0.0 .INDENT 3.5 .sp @@ -414,8 +415,8 @@ When result of \fBdumpdata\fP is saved as a file, it can serve as a .sp Note that \fBdumpdata\fP uses the default manager on the model for selecting the records to dump. If you\(aqre using a \fI\%custom manager\fP as -the default manager and it filters some of the available records, not all of the -objects will be dumped. +the default manager and it filters some of the available records, not all of +the objects will be dumped. .INDENT 0.0 .TP .B \-\-all, \-a @@ -586,12 +587,12 @@ Django doesn\(aqt create database defaults when a Similarly, database defaults aren\(aqt translated to model field defaults or detected in any fashion by \fBinspectdb\fP\&. .sp -By default, \fBinspectdb\fP creates unmanaged models. That is, \fBmanaged = False\fP -in the model\(aqs \fBMeta\fP class tells Django not to manage each table\(aqs creation, -modification, and deletion. If you do want to allow Django to manage the -table\(aqs lifecycle, you\(aqll need to change the -\fI\%managed\fP option to \fBTrue\fP (or remove -it because \fBTrue\fP is its default value). +By default, \fBinspectdb\fP creates unmanaged models. That is, \fBmanaged = +False\fP in the model\(aqs \fBMeta\fP class tells Django not to manage each table\(aqs +creation, modification, and deletion. If you do want to allow Django to manage +the table\(aqs lifecycle, you\(aqll need to change the +\fI\%managed\fP option to \fBTrue\fP (or remove it +because \fBTrue\fP is its default value). .SS Database\-specific notes .SS Oracle .INDENT 0.0 @@ -1108,8 +1109,8 @@ optimized. .UNINDENT .sp Starts a lightweight development web server on the local machine. By default, -the server runs on port 8000 on the IP address \fB127.0.0.1\fP\&. You can pass in an -IP address and port number explicitly. +the server runs on port 8000 on the IP address \fB127.0.0.1\fP\&. You can pass in +an IP address and port number explicitly. .sp If you run this script as a user with normal privileges (recommended), you might not have access to start a port on a low port number. Low port numbers @@ -1212,7 +1213,7 @@ Uses IPv6 for the development server. This changes the default IP address from \fB127.0.0.1\fP to \fB::1\fP\&. .INDENT 0.0 .TP -.B HIDE_PRODUCTION_WARNING +.B DJANGO_RUNSERVER_HIDE_WARNING .UNINDENT .sp @@ -1375,14 +1376,30 @@ Starts the Python interactive interpreter. .sp All models from installed apps are automatically imported into the shell environment. Models from apps listed earlier in \fI\%INSTALLED_APPS\fP take -precedence. For a \fB\-\-verbosity\fP of 2 or higher, the automatically imported -objects will be listed. To disable automatic importing entirely, use the -\fB\-\-no\-imports\fP flag. +precedence. The following common utilities are also imported: +.INDENT 0.0 +.INDENT 3.5 +.sp +.EX +from django.db import connection, reset_queries, models +from django.conf import settings +from django.utils import timezone +.EE +.UNINDENT +.UNINDENT +.sp +For a \fB\-\-verbosity\fP of 2 or higher, the automatically imported objects will +be listed. To disable automatic importing entirely, use the \fB\-\-no\-imports\fP +flag. .sp See the guide on \fI\%customizing this behavior\fP to add or remove automatic imports. .sp Automatic models import was added. +.sp +Automatic imports of common utilities, such as \fBdjango.conf.settings\fP, +were added. + .INDENT 0.0 .TP .B \-\-interface {ipython,bpython,python}, \-i {ipython,bpython,python} @@ -1431,6 +1448,14 @@ default, the script pointed to by the \X'tty: link https://docs.python.org/3/usi variable or the \fB~/.pythonrc.py\fP script is read. .INDENT 0.0 .TP +.B \-\-no\-imports +.UNINDENT +.sp + +.sp +Disables the automatic import of models from \fI\%INSTALLED_APPS\fP\&. +.INDENT 0.0 +.TP .B \-\-command COMMAND, \-c COMMAND .UNINDENT .sp @@ -1560,10 +1585,10 @@ Specifies the database for which to print the SQL. Defaults to \fBdefault\fP\&. .B django\-admin squashmigrations app_label [start_migration_name] migration_name .UNINDENT .sp -Squashes the migrations for \fBapp_label\fP up to and including \fBmigration_name\fP -down into fewer migrations, if possible. The resulting squashed migrations -can live alongside the unsquashed ones safely. For more information, -please read \fI\%Squashing migrations\fP\&. +Squashes the migrations for \fBapp_label\fP up to and including +\fBmigration_name\fP down into fewer migrations, if possible. The resulting +squashed migrations can live alongside the unsquashed ones safely. For more +information, please read \fI\%Squashing migrations\fP\&. .sp When \fBstart_migration_name\fP is given, Django will only include migrations starting from and including this migration. This helps to mitigate the @@ -1611,9 +1636,12 @@ By default, \X'tty: link https://github.com/django/django/blob/main/django/conf/ \fBmodels.py\fP file and other app template files. If only the app name is given, the app directory will be created in the current working directory. .sp -If the optional destination is provided, Django will use that existing -directory rather than creating a new one. You can use \(aq.\(aq to denote the current -working directory. +If the optional destination is provided, Django will use that name instead. If +the directory with the given name doesn\(aqt exist, it will be created. You can +use \(aq.\(aq to denote the current working directory. +.sp +Automatic creation of the destination directory was added. + .sp For example: .INDENT 0.0 @@ -1659,6 +1687,18 @@ django\-admin startapp \-\-template=https://github.com/githubuser/django\-app\-t .EE .UNINDENT .UNINDENT +.sp +\fBWARNING:\fP +.INDENT 0.0 +.INDENT 3.5 +Templates provided via \fB\-\-template\fP are used as is. Malicious or poorly +constructed templates may introduce security weaknesses or unintended +behavior. Compressed archives may also consume excessive resources during +extraction, potentially causing crashes or hangs. +.sp +Contents of templates should be carefully inspected before use. +.UNINDENT +.UNINDENT .INDENT 0.0 .TP .B \-\-extension EXTENSIONS, \-e EXTENSIONS @@ -1750,9 +1790,13 @@ If only the project name is given, both the project directory and project package will be named \fB\fP and the project directory will be created in the current working directory. .sp -If the optional destination is provided, Django will use that existing -directory as the project directory, and create \fBmanage.py\fP and the project -package within it. Use \(aq.\(aq to denote the current working directory. +If the optional destination is provided, Django will use that name as the +project directory, and create \fBmanage.py\fP and the project package within it. +If the directory with the given name doesn\(aqt exist, it will be created. Use \(aq.\(aq +to denote the current working directory. +.sp +Automatic creation of the destination directory was added. + .sp For example: .INDENT 0.0 @@ -1769,7 +1813,10 @@ django\-admin startproject myproject /Users/jezdez/Code/myproject_repo .UNINDENT .sp Specifies a directory, file path, or URL of a custom project template. See the -\fI\%startapp \-\-template\fP documentation for examples and usage. +\fI\%startapp \-\-template\fP documentation for examples and usage. The same +\fBsecurity considerations\fP described for \fBstartapp\fP templates apply here: +malicious or poorly constructed templates may introduce weaknesses or consume +excessive resources, and templates should be carefully inspected before use. .INDENT 0.0 .TP .B \-\-extension EXTENSIONS, \-e EXTENSIONS @@ -2023,13 +2070,6 @@ Outputs timings, including database setup and total run time. .UNINDENT .sp Shows the N slowest test cases (N=0 for all). -.INDENT 0.0 -.INDENT 3.5 -.IP "Python 3.12 and later" -.sp -This feature is only available for Python 3.12 and later. -.UNINDENT -.UNINDENT .SS \fBtestserver\fP .INDENT 0.0 .TP @@ -2064,15 +2104,15 @@ this newly created test database instead of your production database. This is useful in a number of ways: .INDENT 0.0 .IP \(bu 2 -When you\(aqre writing \fI\%unit tests\fP of how your views -act with certain fixture data, you can use \fBtestserver\fP to interact with -the views in a web browser, manually. +When you\(aqre writing \fI\%unit tests\fP of how your +views act with certain fixture data, you can use \fBtestserver\fP to interact +with the views in a web browser, manually. .IP \(bu 2 Let\(aqs say you\(aqre developing your Django application and have a \(dqpristine\(dq copy of a database that you\(aqd like to interact with. You can dump your database to a \fI\%fixture\fP (using the \fI\%dumpdata\fP command, explained above), then use \fBtestserver\fP to run -your web application with that data. With this arrangement, you have the +your web application with that data. With this arrangement, you have the flexibility of messing up your data in any way, knowing that whatever data changes you\(aqre making are only being made to a test database. .UNINDENT @@ -2213,10 +2253,10 @@ it when running interactively. .sp Specifies the database into which the superuser object will be saved. .sp -You can subclass the management command and override \fBget_input_data()\fP if you -want to customize data input and validation. Consult the source code for -details on the existing implementation and the method\(aqs parameters. For example, -it could be useful if you have a \fBForeignKey\fP in +You can subclass the management command and override \fBget_input_data()\fP if +you want to customize data input and validation. Consult the source code for +details on the existing implementation and the method\(aqs parameters. For +example, it could be useful if you have a \fBForeignKey\fP in \fI\%REQUIRED_FIELDS\fP and want to allow creating an instance instead of entering the primary key of an existing instance. @@ -2273,7 +2313,8 @@ Please refer to its \fI\%description\fP in the .sp This command is only available if the \fI\%static files application\fP (\fBdjango.contrib.staticfiles\fP) is installed. .sp -Please refer to its \fI\%description\fP in the \fI\%staticfiles\fP documentation. +Please refer to its \fI\%description\fP in the +\fI\%staticfiles\fP documentation. .SH DEFAULT OPTIONS .sp Although some commands may allow their own custom options, every command @@ -2375,7 +2416,7 @@ django\-admin migrate \-\-verbosity 2 .B \-\-no\-color .UNINDENT .sp -Disables colorized command output. Some commands format their output to be +Disables colorized command output. Some commands format their output to be colorized. For example, errors will be printed to the console in red and SQL statements will be syntax highlighted. .sp @@ -2609,8 +2650,8 @@ overridden as specified. .SS Bash completion .sp If you use the Bash shell, consider installing the Django bash completion -script, which lives in \X'tty: link https://github.com/django/django/blob/main/extras/django_bash_completion'\fI\%extras/django_bash_completion\fP\X'tty: link' in the Django source -distribution. It enables tab\-completion of \fBdjango\-admin\fP and +script, which lives in \X'tty: link https://github.com/django/django/blob/main/extras/django_bash_completion'\fI\%extras/django_bash_completion\fP\X'tty: link' in the Django +source distribution. It enables tab\-completion of \fBdjango\-admin\fP and \fBmanage.py\fP commands, so you can, for instance... .INDENT 0.0 .IP \(bu 2 @@ -2690,7 +2731,8 @@ management.call_command(loaddata.Command(), \(dqtest_data\(dq, verbosity=0) .UNINDENT .sp Note that command options that take no arguments are passed as keywords -with \fBTrue\fP or \fBFalse\fP, as you can see with the \fBinteractive\fP option above. +with \fBTrue\fP or \fBFalse\fP, as you can see with the \fBinteractive\fP option +above. .sp Named arguments can be passed by using either one of the following syntaxes: .INDENT 0.0 From eae8cc42011fc0bf96f0d48d863e65c3c697614a Mon Sep 17 00:00:00 2001 From: Natalia <124304+nessita@users.noreply.github.com> Date: Tue, 16 Sep 2025 23:12:32 -0300 Subject: [PATCH 4/5] Removed empty sections from 6.0 release notes. --- docs/releases/6.0.txt | 120 ------------------------------------------ 1 file changed, 120 deletions(-) diff --git a/docs/releases/6.0.txt b/docs/releases/6.0.txt index 8f0bf321a5fd..4add318acef3 100644 --- a/docs/releases/6.0.txt +++ b/docs/releases/6.0.txt @@ -163,22 +163,12 @@ Minor features * The new :attr:`.AdminSite.password_change_form` attribute allows customizing the form used in the admin site password change view. -:mod:`django.contrib.admindocs` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -* ... - :mod:`django.contrib.auth` ~~~~~~~~~~~~~~~~~~~~~~~~~~ * The default iteration count for the PBKDF2 password hasher is increased from 1,000,000 to 1,200,000. -:mod:`django.contrib.contenttypes` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -* ... - :mod:`django.contrib.gis` ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -202,11 +192,6 @@ Minor features :class:`GeometryType() ` database function allow filtering geometries by their types. -:mod:`django.contrib.messages` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -* ... - :mod:`django.contrib.postgres` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -228,26 +213,6 @@ Minor features parameter. This allows providing database hints to database routers to assist them in :ref:`making routing decisions `. -:mod:`django.contrib.redirects` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -* ... - -:mod:`django.contrib.sessions` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -* ... - -:mod:`django.contrib.sitemaps` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -* ... - -:mod:`django.contrib.sites` -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -* ... - :mod:`django.contrib.staticfiles` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -255,26 +220,6 @@ Minor features ensures consistent path ordering in manifest files, making them more reproducible and reducing unnecessary diffs. -:mod:`django.contrib.syndication` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -* ... - -Cache -~~~~~ - -* ... - -CSRF -~~~~ - -* ... - -Decorators -~~~~~~~~~~ - -* ... - Email ~~~~~ @@ -287,41 +232,6 @@ Email accepts a :class:`~email.message.MIMEPart` object from Python's modern email API. -Error Reporting -~~~~~~~~~~~~~~~ - -* ... - -File Storage -~~~~~~~~~~~~ - -* ... - -File Uploads -~~~~~~~~~~~~ - -* ... - -Forms -~~~~~ - -* ... - -Generic Views -~~~~~~~~~~~~~ - -* ... - -Internationalization -~~~~~~~~~~~~~~~~~~~~ - -* ... - -Logging -~~~~~~~ - -* ... - Management Commands ~~~~~~~~~~~~~~~~~~~ @@ -397,21 +307,6 @@ Requests and Responses * Multiple ``Cookie`` headers are now supported for HTTP/2 requests when running with ASGI. -Security -~~~~~~~~ - -* ... - -Serialization -~~~~~~~~~~~~~ - -* ... - -Signals -~~~~~~~ - -* ... - Templates ~~~~~~~~~ @@ -431,21 +326,6 @@ Tests * The :class:`.DiscoverRunner` now supports parallel test execution on systems using the ``forkserver`` :mod:`multiprocessing` start method. -URLs -~~~~ - -* ... - -Utilities -~~~~~~~~~ - -* ... - -Validators -~~~~~~~~~~ - -* ... - .. _backwards-incompatible-6.0: Backwards incompatible changes in 6.0 From 154aa62e6fe25fa337716503e261590840e24f14 Mon Sep 17 00:00:00 2001 From: Natalia <124304+nessita@users.noreply.github.com> Date: Wed, 17 Sep 2025 10:13:33 -0300 Subject: [PATCH 5/5] Made cosmetic edits to docs/releases/6.0.txt. --- docs/releases/6.0.txt | 89 ++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 47 deletions(-) diff --git a/docs/releases/6.0.txt b/docs/releases/6.0.txt index 4add318acef3..268d7a38c0f2 100644 --- a/docs/releases/6.0.txt +++ b/docs/releases/6.0.txt @@ -18,13 +18,13 @@ project. Python compatibility ==================== -Django 6.0 supports Python 3.12 and 3.13. We **highly recommend** and only -officially support the latest release of each series. +Django 6.0 supports Python 3.12 and 3.13. We **highly recommend**, and only +officially support, the latest release of each series. The Django 5.2.x series is the last to support Python 3.10 and 3.11. -Third-party library support for older version of Django -======================================================= +Third-party library support for older versions of Django +======================================================== Following the release of Django 6.0, we suggest that third-party app authors drop support for all versions of Django prior to 5.2. At that time, you should @@ -75,28 +75,11 @@ guidance, see the :ref:`CSP security overview ` and the :doc:`reference docs `, which include details about decorators to override or disable policies on a per-view basis. -Adoption of Python's modern email API -------------------------------------- - -Email handling in Django now uses Python's modern email API, introduced in -Python 3.6. This API, centered around the -:class:`email.message.EmailMessage` class, offers a cleaner and -Unicode-friendly interface for composing and sending emails. It replaces use of -Python's older legacy (``Compat32``) API, which relied on lower-level MIME -classes (from :mod:`email.mime`) and required more manual handling of -message structure and encoding. - -Notably, the return type of the :meth:`EmailMessage.message() -` method is now an instance of Python's -:class:`email.message.EmailMessage`. This supports the same API as the -previous ``SafeMIMEText`` and ``SafeMIMEMultipart`` return types, but is not an -instance of those now-deprecated classes. - Template Partials ----------------- The :ref:`Django Template Language ` now supports -:ref:`template partials ` , making it easier to encapsulate +:ref:`template partials `, making it easier to encapsulate and reuse small named fragments within a template file. The new tags :ttag:`{% partialdef %} ` and :ttag:`{% partial %} ` define a partial and render it, respectively. @@ -137,19 +120,33 @@ Once defined, tasks can be enqueued through a configured backend:: message="Hello there!", ) -Backends are configured via the :setting:`TASKS` setting. Django provides -two built-in backends, primarily for development and testing: +Backends are configured via the :setting:`TASKS` setting. The :ref:`two +built-in backends ` included in this release are +primarily intended for development and testing. -* :class:`~django.tasks.backends.immediate.ImmediateBackend`: executes tasks - immediately in the same process. -* :class:`~django.tasks.backends.dummy.DummyBackend`: stores tasks without - running them, leaving results in the - :attr:`~django.tasks.TaskResultStatus.READY` state. - -Django only handles task creation and queuing; it does not provide a worker +Django handles task creation and queuing but does not provide a worker mechanism to run tasks. Execution must be managed by external infrastructure, -such as a separate process or service. See :doc:`/topics/tasks` for an -overview, and the :doc:`Tasks reference ` for API details. +such as a separate process or service. + +See :doc:`/topics/tasks` for an overview and the :doc:`Tasks reference +` for API details. + +Adoption of Python's modern email API +------------------------------------- + +Email handling in Django now uses Python's modern email API, introduced in +Python 3.6. This API, centered around the +:class:`email.message.EmailMessage` class, offers a cleaner and +Unicode-friendly interface for composing and sending emails. It replaces use of +Python's older legacy (``Compat32``) API, which relied on lower-level MIME +classes (from :mod:`email.mime`) and required more manual handling of +message structure and encoding. + +Notably, the return type of the :meth:`EmailMessage.message() +` method is now an instance of Python's +:class:`email.message.EmailMessage`. This supports the same API as the +previous ``SafeMIMEText`` and ``SafeMIMEMultipart`` return types, but is not an +instance of those now-deprecated classes. Minor features -------------- @@ -343,13 +340,13 @@ backends. * ``DatabaseOperations.return_insert_columns()`` and ``DatabaseOperations.fetch_returned_insert_rows()`` methods are renamed to ``returning_columns()`` and ``fetch_returned_rows()``, respectively, to - denote they can be used in the context ``UPDATE … RETURNING`` statements as - well as ``INSERT … RETURNING``. + denote they can be used in the context of ``UPDATE … RETURNING`` statements + as well as ``INSERT … RETURNING``. * The ``DatabaseOperations.fetch_returned_insert_columns()`` method is removed and the ``fetch_returned_rows()`` method replacing ``fetch_returned_insert_rows()`` expects both a ``cursor`` and - ``returning_params`` to be provided just like + ``returning_params`` to be provided, just like ``fetch_returned_insert_columns()`` did. * If the database supports ``UPDATE … RETURNING`` statements, backends can set @@ -402,7 +399,7 @@ Email ``DEFAULT_AUTO_FIELD`` setting now defaults to ``BigAutoField`` --------------------------------------------------------------- -Since Django 3.2 when the :setting:`DEFAULT_AUTO_FIELD` setting was added, +Since Django 3.2, when the :setting:`DEFAULT_AUTO_FIELD` setting was added, the default :djadmin:`startproject` template's ``settings.py`` contained:: DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" @@ -418,11 +415,9 @@ In Django 6.0, :setting:`DEFAULT_AUTO_FIELD` now defaults to :class:`django.db.models.BigAutoField` and the aforementioned lines in the project and app templates are removed. -Most projects shouldn't be affected since there has been a system check warning -since Django 3.2 if a project doesn't set :setting:`DEFAULT_AUTO_FIELD`: - - **models.W042**: Auto-created primary key used when not defining a primary - key type, by default ``django.db.models.AutoField``. +Most projects shouldn't be affected, since Django 3.2 has raised the system +check warning **models.W042** for projects that don't set +:setting:`DEFAULT_AUTO_FIELD`. If you haven't dealt with this warning by now, add ``DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'`` to your project's @@ -495,7 +490,7 @@ used parameters. Using positional arguments for these now emits a deprecation warning and will raise a :exc:`TypeError` when the deprecation period ends. * All *optional* parameters (``fail_silently`` and later) must be passed as - keyword arguments to :func:`get_connection`, :func:`mail_admins`, + keyword arguments to :func:`get_connection`, :func:`mail_admins`, :func:`mail_managers`, :func:`send_mail`, and :func:`send_mass_mail`. * All parameters must be passed as keyword arguments when creating an @@ -581,7 +576,7 @@ to remove usage of these features. * The ``FORMS_URLFIELD_ASSUME_HTTPS`` transitional setting is removed. -* The ``django.db.models.sql.datastructures.Join`` no longer fallback to +* The ``django.db.models.sql.datastructures.Join`` no longer falls back to ``get_joining_columns()``. * The ``get_joining_columns()`` method of ``ForeignObject`` and @@ -599,8 +594,8 @@ to remove usage of these features. * The ``get_prefetch_queryset()`` method of related managers and descriptors is removed. -* ``get_prefetcher()`` and ``prefetch_related_objects()`` no longer fallback to - ``get_prefetch_queryset()``. +* ``get_prefetcher()`` and ``prefetch_related_objects()`` no longer fall back + to ``get_prefetch_queryset()``. See :ref:`deprecated-features-5.1` for details on these changes, including how to remove usage of these features. @@ -612,7 +607,7 @@ to remove usage of these features. methods are removed. * The undocumented ``django.utils.itercompat.is_iterable()`` function and the - ``django.utils.itercompat`` module is removed. + ``django.utils.itercompat`` module are removed. * The ``django.contrib.gis.geoip2.GeoIP2.coords()`` method is removed.