django-ninja
django-ninja copied to clipboard
[BUG] @transaction.atomic does *not* rollback if output validation fails.
django-ninja==1.2.1
@transaction.atomic # neither works
@commerce_router.post(
"/checkout/",
response={
200: SuccessResponseSchema,
400: ErrorResponseSchema,
403: ErrorResponseSchema,
500: ErrorResponseSchema,
},
)
@transaction.atomic # neither works
def handler(request, ...):
...
return 201, {...} # accidentally wrong status code to cause an error
The above will return a 500 error, however, no rollback is performed and anything the handler creates in DB are persisted there.
I'm not sure if api.add_exception_handler(...) affect this or not.
Expected behavior: rollback should happen if anything happens with schema validation after returning from the handler.
@elnygren technically your function did not throw any error (you returned 201 and result) - the result matching happens on higher level (django view)
to do that you can use decorate_view:
from ninja.decorators import decorate_view
@commerce_router.post(
"/checkout/",
response={
200: SuccessResponseSchema,
400: ErrorResponseSchema,
403: ErrorResponseSchema,
500: ErrorResponseSchema,
},
)
@decorate_view(transaction.atomic) # <--------
def handler(request, ...):
...
return 201, {...} # accidentally wrong status code to cause an error
@vitalik @decorate_view(transaction.non_atomic_requests()) does not work with ninja, this decorator adds attribute to decorated view and django expect it to have special value but instead of decorated view django gets ninja operation run wrapper method without added attribute.
In other words decorate_view is not fully compatible with all django builtin decorators