Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version 5.0 breaks show_toolbar callback accessing database #2061

Open
adamantike opened this issue Jan 24, 2025 · 3 comments
Open

Version 5.0 breaks show_toolbar callback accessing database #2061

adamantike opened this issue Jan 24, 2025 · 3 comments

Comments

@adamantike
Copy link
Contributor

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.
@tim-schilling
Copy link
Member

Can you confirm that this only happens when you're using an ASGI request? (ASGI_APPLICATION is specified in your settings?)

@tim-schilling
Copy link
Member

I've confirmed it does break for ASGI applications and not WSGI.

@adamantike
Copy link
Contributor Author

Yes, I can confirm it's not reproducible on my end when running runserver with a WSGI application, but it is reproducible when using Django's get_asgi_application(), even without ASGI_APPLICATION setting explicitly set.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants