Skip to content

Commit 0e7711e

Browse files
elinedapre-commit-ci[bot]tim-schilling
authored
1843 new ajax request reset's whole view if history panel is enabled (#1872)
New AJAX request reset's whole view if History Panel is enabled. [+] Create a setting which enable or disable the automatic refresh when an ajax request occurs. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Tim Schilling <[email protected]> Co-authored-by: Tim Schilling <[email protected]>
1 parent 22df01c commit 0e7711e

File tree

11 files changed

+72
-2
lines changed

11 files changed

+72
-2
lines changed

debug_toolbar/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"SQL_WARNING_THRESHOLD": 500, # milliseconds
4343
"OBSERVE_REQUEST_CALLBACK": "debug_toolbar.toolbar.observe_request",
4444
"TOOLBAR_LANGUAGE": None,
45+
"UPDATE_ON_FETCH": False,
4546
}
4647

4748

debug_toolbar/static/debug_toolbar/js/history.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,6 @@ $$.on(djDebug, "click", ".refreshHistory", function (event) {
104104
event.preventDefault();
105105
refreshHistory();
106106
});
107+
// We don't refresh the whole toolbar each fetch or ajax request,
108+
// so we need to refresh the history when we open the panel
109+
$$.onPanelRender(djDebug, "HistoryPanel", refreshHistory);

debug_toolbar/static/debug_toolbar/js/toolbar.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ function getDebugElement() {
1717

1818
const djdt = {
1919
handleDragged: false,
20+
needUpdateOnFetch: false,
2021
init() {
2122
const djDebug = getDebugElement();
23+
djdt.needUpdateOnFetch = djDebug.dataset.updateOnFetch === "True";
2224
$$.on(djDebug, "click", "#djDebugPanelList li a", function (event) {
2325
event.preventDefault();
2426
if (!this.className) {
@@ -274,7 +276,9 @@ const djdt = {
274276
storeId = encodeURIComponent(storeId);
275277
const dest = `${sidebarUrl}?store_id=${storeId}`;
276278
slowjax(dest).then(function (data) {
277-
replaceToolbarState(storeId, data);
279+
if (djdt.needUpdateOnFetch){
280+
replaceToolbarState(storeId, data);
281+
}
278282
});
279283
}
280284

debug_toolbar/templates/debug_toolbar/base.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
data-sidebar-url="{{ history_url }}"
1717
{% endif %}
1818
data-default-show="{% if toolbar.config.SHOW_COLLAPSED %}false{% else %}true{% endif %}"
19-
{{ toolbar.config.ROOT_TAG_EXTRA_ATTRS|safe }}>
19+
{{ toolbar.config.ROOT_TAG_EXTRA_ATTRS|safe }} data-update-on-fetch="{{ toolbar.config.UPDATE_ON_FETCH }}">
2020
<div class="djdt-hidden" id="djDebugToolbar">
2121
<ul id="djDebugPanelList">
2222
<li><a id="djHideToolBarButton" href="#" title="{% trans 'Hide toolbar' %}">{% trans "Hide" %} »</a></li>

docs/changes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ Pending
1919
<https://astral.sh/blog/the-ruff-formatter>`__.
2020
* Changed the default position of the toolbar from top to the upper top
2121
position.
22+
* Added the setting, ``UPDATE_ON_FETCH`` to control whether the
23+
toolbar automatically updates to the latest AJAX request or not.
24+
It defaults to ``False``.
2225

2326
4.2.0 (2023-08-10)
2427
------------------

docs/configuration.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,16 @@ Toolbar options
163163
but want to render your application in French, you would set this to
164164
``"en-us"`` and :setting:`LANGUAGE_CODE` to ``"fr"``.
165165

166+
.. _UPDATE_ON_FETCH:
167+
168+
* ``UPDATE_ON_FETCH``
169+
170+
Default: ``False``
171+
172+
This controls whether the toolbar should update to the latest AJAX
173+
request when it occurs. This is especially useful when using htmx
174+
boosting or similar JavaScript techniques.
175+
166176
Panel options
167177
~~~~~~~~~~~~~
168178

docs/spelling_wordlist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Pympler
66
Roboto
77
Transifex
88
Werkzeug
9+
ajax
910
async
1011
backend
1112
backends

tests/templates/ajax/ajax.html

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{% extends "base.html" %}
2+
{% block content %}
3+
<div id="click_for_ajax">click for ajax</div>
4+
5+
<script>
6+
7+
let click_for_ajax = document.getElementById("click_for_ajax");
8+
function send_ajax() {
9+
let xhr = new XMLHttpRequest();
10+
let url = '/json_view/';
11+
xhr.open("GET", url, true);
12+
xhr.onreadystatechange = function () {
13+
if (this.readyState == 4 && this.status == 200) {
14+
console.log(this.responseText);
15+
}
16+
}
17+
xhr.send();
18+
}
19+
document.addEventListener("click", (event) => {send_ajax()});
20+
</script>
21+
{% endblock %}

tests/test_integration.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
import re
3+
import time
34
import unittest
45

56
import html5lib
@@ -749,3 +750,24 @@ def test_toolbar_language_will_render_to_locale_when_set_both(self):
749750
)
750751
self.assertIn("Query", table.text)
751752
self.assertIn("Action", table.text)
753+
754+
def test_ajax_dont_refresh(self):
755+
self.get("/ajax/")
756+
make_ajax = self.selenium.find_element(By.ID, "click_for_ajax")
757+
make_ajax.click()
758+
history_panel = self.selenium.find_element(By.ID, "djdt-HistoryPanel")
759+
self.assertIn("/ajax/", history_panel.text)
760+
self.assertNotIn("/json_view/", history_panel.text)
761+
762+
@override_settings(DEBUG_TOOLBAR_CONFIG={"UPDATE_ON_FETCH": True})
763+
def test_ajax_refresh(self):
764+
self.get("/ajax/")
765+
make_ajax = self.selenium.find_element(By.ID, "click_for_ajax")
766+
make_ajax.click()
767+
# Need to wait until the ajax request is over and json_view is displayed on the toolbar
768+
time.sleep(2)
769+
history_panel = self.wait.until(
770+
lambda selenium: self.selenium.find_element(By.ID, "djdt-HistoryPanel")
771+
)
772+
self.assertNotIn("/ajax/", history_panel.text)
773+
self.assertIn("/json_view/", history_panel.text)

tests/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
path("cached_low_level_view/", views.cached_low_level_view),
2222
path("json_view/", views.json_view),
2323
path("redirect/", views.redirect_view),
24+
path("ajax/", views.ajax_view),
2425
path("login_without_redirect/", LoginView.as_view(redirect_field_name=None)),
2526
path("admin/", admin.site.urls),
2627
path("__debug__/", include("debug_toolbar.urls")),

tests/views.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,7 @@ def listcomp_view(request):
5858

5959
def redirect_view(request):
6060
return HttpResponseRedirect("/regular/redirect/")
61+
62+
63+
def ajax_view(request):
64+
return render(request, "ajax/ajax.html")

0 commit comments

Comments
 (0)