diff --git a/debug_toolbar/panels/request.py b/debug_toolbar/panels/request.py index 5255624b2..966301d97 100644 --- a/debug_toolbar/panels/request.py +++ b/debug_toolbar/panels/request.py @@ -61,9 +61,11 @@ def generate_stats(self, request, response): if hasattr(request, "session"): self.record_stats( { - "session": [ - (k, request.session.get(k)) - for k in sorted(request.session.keys()) - ] + "session": { + "list": [ + (k, request.session.get(k)) + for k in sorted(request.session.keys()) + ] + } } ) diff --git a/debug_toolbar/static/debug_toolbar/css/toolbar.css b/debug_toolbar/static/debug_toolbar/css/toolbar.css index 2d36049f1..a105bfd11 100644 --- a/debug_toolbar/static/debug_toolbar/css/toolbar.css +++ b/debug_toolbar/static/debug_toolbar/css/toolbar.css @@ -591,6 +591,13 @@ #djDebug .djdt-stack pre.djdt-locals { margin: 0 27px 27px 27px; } +#djDebug .djdt-raw { + background-color: #fff; + border: 1px solid #ccc; + margin-top: 0.8em; + padding: 5px; + white-space: pre-wrap; +} #djDebug .djdt-width-20 { width: 20%; diff --git a/debug_toolbar/templates/debug_toolbar/panels/request.html b/debug_toolbar/templates/debug_toolbar/panels/request.html index 3f9b068be..076d5f74f 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/request.html +++ b/debug_toolbar/templates/debug_toolbar/panels/request.html @@ -20,28 +20,28 @@

{% trans "View information" %}

-{% if cookies %} +{% if cookies.list or cookies.raw %}

{% trans "Cookies" %}

{% include 'debug_toolbar/panels/request_variables.html' with variables=cookies %} {% else %}

{% trans "No cookies" %}

{% endif %} -{% if session %} +{% if session.list or session.raw %}

{% trans "Session data" %}

{% include 'debug_toolbar/panels/request_variables.html' with variables=session %} {% else %}

{% trans "No session data" %}

{% endif %} -{% if get %} +{% if get.list or get.raw %}

{% trans "GET data" %}

{% include 'debug_toolbar/panels/request_variables.html' with variables=get %} {% else %}

{% trans "No GET data" %}

{% endif %} -{% if post %} +{% if post.list or post.raw %}

{% trans "POST data" %}

{% include 'debug_toolbar/panels/request_variables.html' with variables=post %} {% else %} diff --git a/debug_toolbar/templates/debug_toolbar/panels/request_variables.html b/debug_toolbar/templates/debug_toolbar/panels/request_variables.html index 7e9118c7d..92200f867 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/request_variables.html +++ b/debug_toolbar/templates/debug_toolbar/panels/request_variables.html @@ -1,5 +1,6 @@ {% load i18n %} +{% if variables.list %} @@ -12,7 +13,7 @@ - {% for key, value in variables %} + {% for key, value in variables.list %} @@ -20,3 +21,6 @@ {% endfor %}
{{ key|pprint }} {{ value|pprint }}
+{% elif variables.raw %} +{{ variables.raw|pprint }} +{% endif %} diff --git a/debug_toolbar/utils.py b/debug_toolbar/utils.py index 6b80c5af0..cc90cf4db 100644 --- a/debug_toolbar/utils.py +++ b/debug_toolbar/utils.py @@ -231,12 +231,16 @@ def getframeinfo(frame, context=1): def get_sorted_request_variable(variable): """ - Get a sorted list of variables from the request data. + Get a data structure for showing a sorted list of variables from the + request data. """ - if isinstance(variable, dict): - return [(k, variable.get(k)) for k in sorted(variable)] - else: - return [(k, variable.getlist(k)) for k in sorted(variable)] + try: + if isinstance(variable, dict): + return {"list": [(k, variable.get(k)) for k in sorted(variable)]} + else: + return {"list": [(k, variable.getlist(k)) for k in sorted(variable)]} + except TypeError: + return {"raw": variable} def get_stack(context=1): diff --git a/docs/changes.rst b/docs/changes.rst index e4256d11d..83e8fe9aa 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -3,6 +3,10 @@ Change log * Removed third party panels which have been archived on GitHub. * Added Django 4.1a1 to the CI matrix. +* Stopped crashing when ``request.GET`` and ``request.POST`` are neither + dictionaries nor ``QueryDict`` instances. Using anything but ``QueryDict`` + instances isn't a valid use of Django but, again, django-debug-toolbar + shouldn't crash. 3.4.0 (2022-05-03) ------------------ diff --git a/tests/panels/test_request.py b/tests/panels/test_request.py index 1d2a33c56..8087203c3 100644 --- a/tests/panels/test_request.py +++ b/tests/panels/test_request.py @@ -85,6 +85,19 @@ def test_dict_for_request_in_method_post(self): self.assertIn("foo", content) self.assertIn("bar", content) + def test_list_for_request_in_method_post(self): + """ + Verify that the toolbar doesn't crash if request.POST contains unexpected data. + + See https://github.com/jazzband/django-debug-toolbar/issues/1621 + """ + self.request.POST = [{"a": 1}, {"b": 2}] + response = self.panel.process_request(self.request) + self.panel.generate_stats(self.request, response) + # ensure the panel POST request data is processed correctly. + content = self.panel.content + self.assertIn("[{'a': 1}, {'b': 2}]", content) + def test_namespaced_url(self): self.request.path = "/admin/login/" response = self.panel.process_request(self.request)