django-ninja
django-ninja copied to clipboard
[BUG] django's `@non_atomic_requests` decorator does not work with ninja views
Describe the bug
When using ATOMIC_REQUESTS, django has a decorator, @non_atomic_requests, to opt-out on a specific view. This is necessary e.g. when you want to mix sync and async views, since async views don't support transactions.
Applying this decorator to a ninja view doesn't work:
@api.post("/foo/bar")
@non_atomic_requests
async def foo_bar(request):
pass
That will fail with RuntimeError: You cannot use ATOMIC_REQUESTS with async views. if using ATOMIC_REQUESTS.
The decorator doesn't work on sync views either. The decorator works by setting a property on the view function itself, and since Ninja uses its own view functions, that property isn't preserved.
There is a very hacky workaround:
@api.post("/foo/bar")
@non_atomic_requests
async def foo_bar(request):
pass
transaction.non_atomic_requests(
api.path_operations["/foo/bar"]._async_view.__func__ # or _sync_view
)
Versions (please complete the following information):
- Python version: 3.10
- Django version: 4.1
- Django-Ninja version: 0.19.1
- Pydantic version: 1.10.2
@vitalik Hi! Could i look into this issue? this issue is still valid?
Hi @baidoosik
I think this decorator works on the view level.. try this (in django ninja 1.x):
from ninja.decorators import decorate_view
@api.post("/foo/bar")
@decorate_view(non_atomic_requests)
async def foo_bar(request):
pass
@vitalik Thanks! I just ask this because this issue has help wanted tag. If there is any issue i can contribute, please share!