Open
Description
Description
Since version 5.0, setting SHOW_TOOLBAR_CALLBACK
to a function that uses the ORM to access the database raises the following exception:
SynchronousOnlyOperation
You cannot call this from an async context - use a thread or sync_to_async.
An example function that triggers this issue:
def show_toolbar(request):
return request.user.is_staff
As request.user
is a lazy object, it'll be retrieved during the show_toolbar
execution. As some panels are asynchronous now, Django Debug Toolbar will try to access to the database from an asynchronous context.
Converting the callback to asynchronous does not work either, because:
- The
DebugToolbarMiddleware.__acall__
method does not await for theshow_toolbar(request)
call. - The
DebugToolbarMiddleware.__call__
method callsshow_toolbar(request)
, which will always be true, as Python will return a coroutine object.
Possible solution
Allow both sync and async SHOW_TOOLBAR_CALLBACK
functions, and:
- In
DebugToolbarMiddleware.__call__
method, cast the callback usingasync_to_sync
if the provided function is asynchronous. - In
DebugToolbarMiddleware.__acall__
method, cast the callback usingsync_to_async
if the provided function is synchronous, and add theawait
to its execution.