Skip to content

Commit 84a3296

Browse files
committed
Fix missing query-actions buttons for queries with date/datetime params.
The param `strings_only=True` caused params with type `time`, `date` and `datetime` to not be converted to string by `NormalCursorWrapper._decode()`, and in turn causes the json dumping to fail. This change keeps `strings_only=True` for every type but datetime, date and time, enabling conversion to string in those cases. Fixes #882
1 parent b7672d9 commit 84a3296

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

debug_toolbar/panels/sql/tracking.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import absolute_import, unicode_literals
22

3+
import datetime
34
import json
45
from threading import local
56
from time import time
@@ -95,8 +96,10 @@ def _quote_params(self, params):
9596
return [self._quote_expr(p) for p in params]
9697

9798
def _decode(self, param):
99+
# make sure datetime, date and time are converted to string by force_text
100+
CONVERT_TYPES = (datetime.datetime, datetime.date, datetime.time)
98101
try:
99-
return force_text(param, strings_only=True)
102+
return force_text(param, strings_only=not isinstance(param, CONVERT_TYPES))
100103
except UnicodeDecodeError:
101104
return '(encoded string)'
102105

@@ -114,7 +117,7 @@ def _record(self, method, sql, params):
114117
_params = ''
115118
try:
116119
_params = json.dumps([self._decode(p) for p in params])
117-
except Exception:
120+
except TypeError as e:
118121
pass # object not JSON serializable
119122

120123
template_info = get_template_info()

tests/panels/test_sql.py

+31
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
from __future__ import absolute_import, unicode_literals
44

5+
import datetime
56
import unittest
67

78
from django.contrib.auth.models import User
89
from django.db import connection
10+
from django.db.models import Count
911
from django.db.utils import DatabaseError
1012
from django.shortcuts import render
1113
from django.test.utils import override_settings
@@ -69,6 +71,35 @@ def test_non_ascii_query(self):
6971
# ensure the panel renders correctly
7072
self.assertIn('café', self.panel.content)
7173

74+
def test_param_conversion(self):
75+
self.assertEqual(len(self.panel._queries), 0)
76+
77+
list(
78+
User.objects
79+
.filter(first_name='Foo')
80+
.filter(is_staff=True)
81+
.filter(is_superuser=False)
82+
)
83+
list(
84+
User.objects
85+
.annotate(group_count=Count('groups__id'))
86+
.filter(group_count__lt=10)
87+
.filter(group_count__gt=1)
88+
)
89+
list(User.objects.filter(date_joined=datetime.datetime(2017, 12, 22, 16, 7, 1)))
90+
91+
self.panel.process_response(self.request, self.response)
92+
self.panel.generate_stats(self.request, self.response)
93+
94+
# ensure query was logged
95+
self.assertEqual(len(self.panel._queries), 3)
96+
97+
self.assertEqual(tuple([q[1]['params'] for q in self.panel._queries]), (
98+
'["Foo", true, false]',
99+
'[10, 1]',
100+
'["2017-12-22 16:07:01"]'
101+
))
102+
72103
def test_insert_content(self):
73104
"""
74105
Test that the panel only inserts content after generate_stats and

0 commit comments

Comments
 (0)