﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
37382	@non_atomic_requests no longer works on async views	Jacob Walls		"After bdbda29c3e126754c3ae04ceb5c5d35d49aae01c (#29303), `@non_atomic_requests` wraps all views in a sync callable regardless if the view was a coroutine. This test passes on 6.1:

{{{#!diff
diff --git a/tests/handlers/tests.py b/tests/handlers/tests.py
index 240c398988..c641aeb82a 100644
--- a/tests/handlers/tests.py
+++ b/tests/handlers/tests.py
@@ -155,6 +155,15 @@ class TransactionsPerRequestTests(TransactionTestCase):
         self.assertEqual(wrapped_once._non_atomic_requests, {""default""})
         self.assertEqual(wrapped_twice._non_atomic_requests, {""default"", ""other""})
 
+    async def test_no_auto_transaction_async(self):
+        old_atomic_requests = connection.settings_dict[""ATOMIC_REQUESTS""]
+        try:
+            connection.settings_dict[""ATOMIC_REQUESTS""] = True
+            response = await self.async_client.get(""/not_in_transaction_async/"")
+        finally:
+            connection.settings_dict[""ATOMIC_REQUESTS""] = old_atomic_requests
+        self.assertContains(response, ""False"")
+
 
 @override_settings(ROOT_URLCONF=""handlers.urls"")
 class SignalsTests(SimpleTestCase):
diff --git a/tests/handlers/urls.py b/tests/handlers/urls.py
index a0efece602..8c7b65e018 100644
--- a/tests/handlers/urls.py
+++ b/tests/handlers/urls.py
@@ -11,6 +11,7 @@ urlpatterns = [
     path(""async_streaming/"", views.async_streaming),
     path(""in_transaction/"", views.in_transaction),
     path(""not_in_transaction/"", views.not_in_transaction),
+    path(""not_in_transaction_async/"", views.not_in_transaction_async),
     path(""not_in_transaction_using_none/"", views.not_in_transaction_using_none),
     path(""not_in_transaction_using_text/"", views.not_in_transaction_using_text),
     path(""bad_request/"", views.bad_request),
diff --git a/tests/handlers/views.py b/tests/handlers/views.py
index 95d663323d..fe72c600ae 100644
--- a/tests/handlers/views.py
+++ b/tests/handlers/views.py
@@ -33,6 +33,11 @@ def not_in_transaction(request):
     return HttpResponse(str(connection.in_atomic_block))
 
 
+@transaction.non_atomic_requests
+async def not_in_transaction_async(request):
+    return HttpResponse(str(connection.in_atomic_block))
+
+
 @transaction.non_atomic_requests(using=None)
 def not_in_transaction_using_none(request):
     return HttpResponse(str(connection.in_atomic_block))
}}}
{{{#!py
Exception ignored while finalizing coroutine <coroutine object not_in_transaction_async at 0x10a5812a0>:
Traceback (most recent call last):
  File ""/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14/_py_warnings.py"", line 856, in _warn_unawaited_coroutine
    _wm.warn(
RuntimeWarning: coroutine 'not_in_transaction_async' was never awaited

======================================================================
ERROR: test_no_auto_transaction_async (handlers.tests.TransactionsPerRequestTests.test_no_auto_transaction_async)
----------------------------------------------------------------------
Traceback (most recent call last):
  File ""/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14/unittest/case.py"", line 58, in testPartExecutor
    yield
  File ""/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14/unittest/case.py"", line 669, in run
    self._callTestMethod(testMethod)
    
  File ""/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14/unittest/case.py"", line 615, in _callTestMethod
    result = method()
    ^^^^^^^^^^^^^^^
  File ""/Users/jwalls/my314/lib/python3.14/site-packages/asgiref/sync.py"", line 332, in __call__
    return call_result.result()
    ^^^^^^^^^^^^^^^
  File ""/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14/concurrent/futures/_base.py"", line 447, in result
    return self.__get_result()
    ^^^
  File ""/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14/concurrent/futures/_base.py"", line 396, in __get_result
    raise self._exception
    ^^^^^^^
  File ""/Users/jwalls/my314/lib/python3.14/site-packages/asgiref/sync.py"", line 372, in main_wrap
    result = await awaitable
    ^^^^^^^
  File ""/Users/jwalls/django/tests/handlers/tests.py"", line 162, in test_no_auto_transaction_async
    response = await self.async_client.get(""/not_in_transaction_async/"")
    ^^^^^^^^^^^
  File ""/Users/jwalls/django/django/test/client.py"", line 1495, in get
    response = await super().get(
    ^^^^^^^^^^^^^^^
  File ""/Users/jwalls/django/django/test/client.py"", line 1458, in request
    self.check_exception(response)
    ^^^^^^^^^^^^^^^
  File ""/Users/jwalls/django/django/test/client.py"", line 810, in check_exception
    raise exc_value
    ^^^^^^^
  File ""/Users/jwalls/my314/lib/python3.14/site-packages/asgiref/sync.py"", line 577, in thread_handler
    raise exc_info[1]
    ^^^^^^^
  File ""/Users/jwalls/django/django/core/handlers/exception.py"", line 43, in inner
    response = await get_response(request)
    ^^^^^^^
  File ""/Users/jwalls/django/django/core/handlers/base.py"", line 267, in _get_response_async
    self.check_response(response, callback)
    ^^^^^^^^^^^^^^^
  File ""/Users/jwalls/django/django/core/handlers/base.py"", line 339, in check_response
    raise ValueError(
    ^^^^^^^^^^^
ValueError: The view handlers.views.not_in_transaction_async didn't return an HttpResponse object. It returned an unawaited coroutine instead. You may need to add an 'await' into your view.

----------------------------------------------------------------------
Ran 42 tests in 1.277s

FAILED (errors=1)
}}}

----
My understanding is that using this decorator is **required** for async views to avoid the safety check here:
{{{#!py
    def make_view_atomic(self, view):
        non_atomic_requests = getattr(view, ""_non_atomic_requests"", set())
        for alias, settings_dict in connections.settings.items():
            if settings_dict[""ATOMIC_REQUESTS""] and alias not in non_atomic_requests:
                if iscoroutinefunction(view):
                    raise RuntimeError(
                        ""You cannot use ATOMIC_REQUESTS with async views.""
                    )
                view = transaction.atomic(using=alias)(view)
        return view
}}}"	Bug	new	Database layer (models, ORM)	dev	Release blocker			Sina Chaichi	Unreviewed	0	0	0	0	0	0
