Skip to content

Support serializable toolbar #2138

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

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open

Support serializable toolbar #2138

wants to merge 27 commits into from

Conversation

tim-schilling
Copy link
Member

@tim-schilling tim-schilling commented May 15, 2025

Description

This change significantly revamps how panels for the toolbar work. Each panel will now persist its data in a store. A store can either be backed by various backends. The toolbar will support a memory and database backend to start.

Django applications with basic installations are backwards compatible with this change. If there are hooks into the internals of the toolbar, such as DebugToolbar.store_id then it will be backwards incompatible.

Third-party panels will need updating. Any data that is stored in record_stats will need to be fetched back out from self.get_stats() before being able to be rendered. This is to support loading an instance of the toolbar from persisted data. A simple example of this transition can be found in debug_toolbar/panels/cache.py in this PR.

Refs: #1435, #2048, #2124

Checklist:

  • I have added the relevant tests for this change.
  • I have added an item to the Pending section of docs/changes.rst.

tim-schilling and others added 26 commits August 20, 2023 14:19
If the serialization logic begins throwing exceptions we can consider
subclassing the encoder class and using force_str on the object itself.
* Log serialization warning when a panel errors.

This will help third party panels identify issues with serializing
the content of their panels in the future, without causing the
entire toolbar to break.

* Change setting name to SUPPRESS_SERIALIZATION_ERRORS
This matches the new naming defined in the store module and will make
things eaiser to change moving forward.

This will break anything using the store internally causing issues for
third party packages.
The remainder of the work is to fix the individual panels' serialization errors.
This avoids needing to create an instance of a panel to get its
panel ID.
The alternative here is to inspect and iterate over every collection and
object passed around. This avoids having to reinvent the wheel in that
scenario.
Any instance attributes shouldn't be used because they can't be
relied upon for historical purposes. Especially when it comes to
the titles and nav titles.
The alerts panel may eventually have other types of alerts that
don't depend on the response. Such as Django's check system.
The stats must be stored as JSON, otherwise it'll be
converted to a string.
This causes problems with tests and changing the settings
via override_settings. Since we're using the lru_cache
decorator on get_config, there's very little benefit to
caching within the store too.
The majority were difficulities with caching and settings.
- Add async union view for tests.

- Add async json explain for tests.
…#2121)

* feat: add DatabaseStore for persistent debug data storage

- Introduced `DatabaseStore` to store debug toolbar data in the database.
- Added `DebugToolbarEntry` model and migrations for persistent storage.
- Updated documentation to include configuration for `DatabaseStore`.
- Added tests for `DatabaseStore` functionality, including CRUD
  operations and cache size enforcement.

Fixes #2073

* refactor: rename DebugToolbarEntry to HistoryEntry and more

- Updated model name from `DebugToolbarEntry` to `HistoryEntry` to make
  string representations of the app_model less redundant.
- Adjusted verbose names to use translations with `gettext_lazy`.
- Updated all references in `store.py` to use the new model name.
- Modified tests to reflect the model name change.
- Added a test to check the default ordering of the model and make it
  the default ordering in methods reliable.

* Optimize entry creation logic to clean up old entries only when new entries are added

* Wrap creation and update methods in atomic transactions

* Avoid using .set() for database store

This doesn't provide the same utility as it does for the memory
store. We need to use get_or_create to generate the entry in the
database regardless. The middleware will be using .set() to trim
extra requests to avoid overflowing the store removing the need
for save_panel to also do the same.

---------

Co-authored-by: Tim Schilling <[email protected]>
@tim-schilling
Copy link
Member Author

The lint failure is from main and due to our usage of document.cookie.

This was missed in an earlier merge.
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

Successfully merging this pull request may close these issues.

2 participants