Skip to content

Version 5.0 breaks show_toolbar callback accessing database #2061

Open
@adamantike

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 the show_toolbar(request) call.
  • The DebugToolbarMiddleware.__call__ method calls show_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 using async_to_sync if the provided function is asynchronous.
  • In DebugToolbarMiddleware.__acall__ method, cast the callback using sync_to_async if the provided function is synchronous, and add the await to its execution.

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions