Skip to content

Commit 62ef502

Browse files
authored
Fix django unicode error (#2217)
* fix for django unicode decode error * created sanitize.py file * changed import reference of force_str to sanitize.py
1 parent 24e9065 commit 62ef502

File tree

9 files changed

+40
-9
lines changed

9 files changed

+40
-9
lines changed

.git-blame-ignore-revs

Whitespace-only changes.

debug_toolbar/forms.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
from django import forms
44
from django.core import signing
55
from django.core.exceptions import ValidationError
6-
from django.utils.encoding import force_str
6+
7+
from debug_toolbar.sanitize import force_str
78

89

910
class SignedDataForm(forms.Form):

debug_toolbar/panels/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
from django.utils.encoding import force_str
21
from django.utils.translation import gettext_lazy as _
32
from django.views.debug import get_default_exception_reporter_filter
43

54
from debug_toolbar.panels import Panel
5+
from debug_toolbar.sanitize import force_str
66

77
get_safe_settings = get_default_exception_reporter_filter().get_safe_settings
88

debug_toolbar/panels/sql/tracking.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
from time import perf_counter
66

77
import django.test.testcases
8-
from django.utils.encoding import force_str
98

9+
from debug_toolbar.sanitize import force_str
1010
from debug_toolbar.utils import get_stack_trace, get_template_info
1111

1212
try:
@@ -128,10 +128,7 @@ def _decode(self, param):
128128

129129
# make sure datetime, date and time are converted to string by force_str
130130
CONVERT_TYPES = (datetime.datetime, datetime.date, datetime.time)
131-
try:
132-
return force_str(param, strings_only=not isinstance(param, CONVERT_TYPES))
133-
except UnicodeDecodeError:
134-
return "(encoded string)"
131+
return force_str(param, strings_only=not isinstance(param, CONVERT_TYPES))
135132

136133
def _last_executed_query(self, sql, params):
137134
"""Get the last executed query from the connection."""

debug_toolbar/panels/templates/panel.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
from django.test.signals import template_rendered
1111
from django.test.utils import instrumented_test_render
1212
from django.urls import path
13-
from django.utils.encoding import force_str
1413
from django.utils.translation import gettext_lazy as _
1514

1615
from debug_toolbar.panels import Panel
1716
from debug_toolbar.panels.sql.tracking import SQLQueryTriggered, allow_sql
1817
from debug_toolbar.panels.templates import views
18+
from debug_toolbar.sanitize import force_str
1919

2020
if find_spec("jinja2"):
2121
from debug_toolbar.panels.templates.jinja2 import patch_jinja_render

debug_toolbar/sanitize.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from django.utils.encoding import DjangoUnicodeDecodeError, force_str as force_string
2+
3+
4+
def force_str(s, *args, **kwargs):
5+
"""
6+
Forces values to strings.
7+
Will return "Django Debug Toolbar was unable to parse value." when there's a decoding error.
8+
"""
9+
try:
10+
return force_string(s, *args, **kwargs)
11+
except DjangoUnicodeDecodeError:
12+
return "Django Debug Toolbar was unable to parse value."

debug_toolbar/store.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66

77
from django.core.serializers.json import DjangoJSONEncoder
88
from django.db import transaction
9-
from django.utils.encoding import force_str
109
from django.utils.module_loading import import_string
1110

1211
from debug_toolbar import settings as dt_settings
1312
from debug_toolbar.models import HistoryEntry
13+
from debug_toolbar.sanitize import force_str
1414

1515

1616
class DebugToolbarJSONEncoder(DjangoJSONEncoder):

docs/changes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ Pending
1616
* Upgraded CI ``postgis`` version to 17-3.5.
1717
* Added how to generate the documentation locally to the contributing
1818
documentation.
19+
* Updated logic that forces values to strings (``force_str``) to render
20+
"Django Debug Toolbar was unable to parse value." when there's a decoding
21+
error.
1922

2023
6.0.0 (2025-07-22)
2124
------------------

tests/test_sanitize.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import unittest
2+
3+
from debug_toolbar.sanitize import force_str
4+
5+
6+
class ForceStrTestCase(unittest.TestCase):
7+
def test_success_convert(self):
8+
input = 0
9+
10+
self.assertEqual(force_str(input), "0")
11+
12+
def test_failed_convert(self):
13+
input = bytes.fromhex(
14+
"a3f2b8c14e972d5a8fb3c7291a64e0859c472bf63d18a0945e73b2c84f917ae2"
15+
)
16+
self.assertEqual(
17+
force_str(input), "Django Debug Toolbar was unable to parse value."
18+
)

0 commit comments

Comments
 (0)