From 3bf2b74f59a2195854157e5b283ccb4fb5e73d11 Mon Sep 17 00:00:00 2001
From: Daniel %s
") % settings.SETTINGS_MODULE
def generate_stats(self, request, response):
- self.record_stats({
- 'settings': OrderedDict(sorted(get_safe_settings().items(),
- key=lambda s: s[0])),
- })
+ self.record_stats(
+ {
+ "settings": OrderedDict(
+ sorted(get_safe_settings().items(), key=lambda s: s[0])
+ )
+ }
+ )
diff --git a/debug_toolbar/panels/signals.py b/debug_toolbar/panels/signals.py
index cd647dbad..80796a4f4 100644
--- a/debug_toolbar/panels/signals.py
+++ b/debug_toolbar/panels/signals.py
@@ -2,13 +2,17 @@
import weakref
-from django.core.signals import (
- got_request_exception, request_finished, request_started,
-)
+from django.core.signals import got_request_exception, request_finished, request_started
from django.db.backends.signals import connection_created
from django.db.models.signals import (
- class_prepared, post_delete, post_init, post_migrate, post_save,
- pre_delete, pre_init, pre_save,
+ class_prepared,
+ post_delete,
+ post_init,
+ post_migrate,
+ post_save,
+ pre_delete,
+ pre_init,
+ pre_save,
)
from django.utils.module_loading import import_string
from django.utils.translation import ugettext_lazy as _, ungettext
@@ -17,45 +21,48 @@
class SignalsPanel(Panel):
- template = 'debug_toolbar/panels/signals.html'
+ template = "debug_toolbar/panels/signals.html"
SIGNALS = {
- 'request_started': request_started,
- 'request_finished': request_finished,
- 'got_request_exception': got_request_exception,
- 'connection_created': connection_created,
- 'class_prepared': class_prepared,
- 'pre_init': pre_init,
- 'post_init': post_init,
- 'pre_save': pre_save,
- 'post_save': post_save,
- 'pre_delete': pre_delete,
- 'post_delete': post_delete,
- 'post_migrate': post_migrate,
+ "request_started": request_started,
+ "request_finished": request_finished,
+ "got_request_exception": got_request_exception,
+ "connection_created": connection_created,
+ "class_prepared": class_prepared,
+ "pre_init": pre_init,
+ "post_init": post_init,
+ "pre_save": pre_save,
+ "post_save": post_save,
+ "pre_delete": pre_delete,
+ "post_delete": post_delete,
+ "post_migrate": post_migrate,
}
def nav_subtitle(self):
- signals = self.get_stats()['signals']
+ signals = self.get_stats()["signals"]
num_receivers = sum(len(s[2]) for s in signals)
num_signals = len(signals)
# here we have to handle a double count translation, hence the
# hard coding of one signal
if num_signals == 1:
- return ungettext("%(num_receivers)d receiver of 1 signal",
- "%(num_receivers)d receivers of 1 signal",
- num_receivers) % {'num_receivers': num_receivers}
- return ungettext("%(num_receivers)d receiver of %(num_signals)d signals",
- "%(num_receivers)d receivers of %(num_signals)d signals",
- num_receivers) % {'num_receivers': num_receivers,
- 'num_signals': num_signals}
+ return ungettext(
+ "%(num_receivers)d receiver of 1 signal",
+ "%(num_receivers)d receivers of 1 signal",
+ num_receivers,
+ ) % {"num_receivers": num_receivers}
+ return ungettext(
+ "%(num_receivers)d receiver of %(num_signals)d signals",
+ "%(num_receivers)d receivers of %(num_signals)d signals",
+ num_receivers,
+ ) % {"num_receivers": num_receivers, "num_signals": num_signals}
title = _("Signals")
@property
def signals(self):
signals = self.SIGNALS.copy()
- for signal in self.toolbar.config['EXTRA_SIGNALS']:
- signal_name = signal.rsplit('.', 1)[-1]
+ for signal in self.toolbar.config["EXTRA_SIGNALS"]:
+ signal_name = signal.rsplit(".", 1)[-1]
signals[signal_name] = import_string(signal)
return signals
@@ -70,12 +77,14 @@ def generate_stats(self, request, response):
if receiver is None:
continue
- receiver = getattr(receiver, '__wraps__', receiver)
- receiver_name = getattr(receiver, '__name__', str(receiver))
- if getattr(receiver, '__self__', None) is not None:
- receiver_class_name = getattr(receiver.__self__, '__class__', type).__name__
+ receiver = getattr(receiver, "__wraps__", receiver)
+ receiver_name = getattr(receiver, "__name__", str(receiver))
+ if getattr(receiver, "__self__", None) is not None:
+ receiver_class_name = getattr(
+ receiver.__self__, "__class__", type
+ ).__name__
text = "%s.%s" % (receiver_class_name, receiver_name)
- elif getattr(receiver, 'im_class', None) is not None: # Python 2 only
+ elif getattr(receiver, "im_class", None) is not None: # Python 2 only
receiver_class_name = receiver.im_class.__name__
text = "%s.%s" % (receiver_class_name, receiver_name)
else:
@@ -83,4 +92,4 @@ def generate_stats(self, request, response):
receivers.append(text)
signals.append((name, signal, receivers))
- self.record_stats({'signals': signals})
+ self.record_stats({"signals": signals})
diff --git a/debug_toolbar/panels/sql/forms.py b/debug_toolbar/panels/sql/forms.py
index a4e622f51..6cc1554a1 100644
--- a/debug_toolbar/panels/sql/forms.py
+++ b/debug_toolbar/panels/sql/forms.py
@@ -25,18 +25,19 @@ class SQLSelectForm(forms.Form):
duration: time for SQL to execute passed in from toolbar just for redisplay
hash: the hash of (secret + sql + params) for tamper checking
"""
+
sql = forms.CharField()
raw_sql = forms.CharField()
params = forms.CharField()
- alias = forms.CharField(required=False, initial='default')
+ alias = forms.CharField(required=False, initial="default")
duration = forms.FloatField()
hash = forms.CharField()
def __init__(self, *args, **kwargs):
- initial = kwargs.get('initial', None)
+ initial = kwargs.get("initial", None)
if initial is not None:
- initial['hash'] = self.make_hash(initial)
+ initial["hash"] = self.make_hash(initial)
super(SQLSelectForm, self).__init__(*args, **kwargs)
@@ -44,23 +45,23 @@ def __init__(self, *args, **kwargs):
self.fields[name].widget = forms.HiddenInput()
def clean_raw_sql(self):
- value = self.cleaned_data['raw_sql']
+ value = self.cleaned_data["raw_sql"]
- if not value.lower().strip().startswith('select'):
+ if not value.lower().strip().startswith("select"):
raise ValidationError("Only 'select' queries are allowed.")
return value
def clean_params(self):
- value = self.cleaned_data['params']
+ value = self.cleaned_data["params"]
try:
return json.loads(value)
except ValueError:
- raise ValidationError('Is not valid JSON')
+ raise ValidationError("Is not valid JSON")
def clean_alias(self):
- value = self.cleaned_data['alias']
+ value = self.cleaned_data["alias"]
if value not in connections:
raise ValidationError("Database alias '%s' not found" % value)
@@ -68,25 +69,25 @@ def clean_alias(self):
return value
def clean_hash(self):
- hash = self.cleaned_data['hash']
+ hash = self.cleaned_data["hash"]
if not constant_time_compare(hash, self.make_hash(self.data)):
- raise ValidationError('Tamper alert')
+ raise ValidationError("Tamper alert")
return hash
def reformat_sql(self):
- return reformat_sql(self.cleaned_data['sql'])
+ return reformat_sql(self.cleaned_data["sql"])
def make_hash(self, data):
m = hmac.new(key=force_bytes(settings.SECRET_KEY), digestmod=hashlib.sha1)
- for item in [data['sql'], data['params']]:
+ for item in [data["sql"], data["params"]]:
m.update(force_bytes(item))
return m.hexdigest()
@property
def connection(self):
- return connections[self.cleaned_data['alias']]
+ return connections[self.cleaned_data["alias"]]
@cached_property
def cursor(self):
diff --git a/debug_toolbar/panels/sql/panel.py b/debug_toolbar/panels/sql/panel.py
index 89a93bb9d..fac9c473b 100644
--- a/debug_toolbar/panels/sql/panel.py
+++ b/debug_toolbar/panels/sql/panel.py
@@ -13,15 +13,14 @@
from debug_toolbar.panels.sql import views
from debug_toolbar.panels.sql.forms import SQLSelectForm
from debug_toolbar.panels.sql.tracking import unwrap_cursor, wrap_cursor
-from debug_toolbar.panels.sql.utils import (
- contrasting_color_generator, reformat_sql,
-)
+from debug_toolbar.panels.sql.utils import contrasting_color_generator, reformat_sql
from debug_toolbar.utils import render_stacktrace
def get_isolation_level_display(vendor, level):
- if vendor == 'postgresql':
+ if vendor == "postgresql":
import psycopg2.extensions
+
choices = {
psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT: _("Autocommit"),
psycopg2.extensions.ISOLATION_LEVEL_READ_UNCOMMITTED: _("Read uncommitted"),
@@ -35,8 +34,9 @@ def get_isolation_level_display(vendor, level):
def get_transaction_status_display(vendor, level):
- if vendor == 'postgresql':
+ if vendor == "postgresql":
import psycopg2.extensions
+
choices = {
psycopg2.extensions.TRANSACTION_STATUS_IDLE: _("Idle"),
psycopg2.extensions.TRANSACTION_STATUS_ACTIVE: _("Active"),
@@ -54,6 +54,7 @@ class SQLPanel(Panel):
Panel that displays information about the SQL queries run while processing
the request.
"""
+
def __init__(self, *args, **kwargs):
super(SQLPanel, self).__init__(*args, **kwargs)
self._offset = {k: len(connections[k].queries) for k in connections}
@@ -71,7 +72,7 @@ def get_transaction_id(self, alias):
if not conn:
return
- if conn.vendor == 'postgresql':
+ if conn.vendor == "postgresql":
cur_status = conn.get_transaction_status()
else:
raise ValueError(conn.vendor)
@@ -95,13 +96,13 @@ def record(self, alias, **kwargs):
self._queries.append((alias, kwargs))
if alias not in self._databases:
self._databases[alias] = {
- 'time_spent': kwargs['duration'],
- 'num_queries': 1,
+ "time_spent": kwargs["duration"],
+ "num_queries": 1,
}
else:
- self._databases[alias]['time_spent'] += kwargs['duration']
- self._databases[alias]['num_queries'] += 1
- self._sql_time += kwargs['duration']
+ self._databases[alias]["time_spent"] += kwargs["duration"]
+ self._databases[alias]["num_queries"] += 1
+ self._sql_time += kwargs["duration"]
self._num_queries += 1
# Implement the Panel API
@@ -110,24 +111,28 @@ def record(self, alias, **kwargs):
@property
def nav_subtitle(self):
- return __("%d query in %.2fms", "%d queries in %.2fms",
- self._num_queries) % (self._num_queries, self._sql_time)
+ return __("%d query in %.2fms", "%d queries in %.2fms", self._num_queries) % (
+ self._num_queries,
+ self._sql_time,
+ )
@property
def title(self):
count = len(self._databases)
- return __('SQL queries from %(count)d connection',
- 'SQL queries from %(count)d connections',
- count) % {'count': count}
+ return __(
+ "SQL queries from %(count)d connection",
+ "SQL queries from %(count)d connections",
+ count,
+ ) % {"count": count}
- template = 'debug_toolbar/panels/sql.html'
+ template = "debug_toolbar/panels/sql.html"
@classmethod
def get_urls(cls):
return [
- url(r'^sql_select/$', views.sql_select, name='sql_select'),
- url(r'^sql_explain/$', views.sql_explain, name='sql_explain'),
- url(r'^sql_profile/$', views.sql_profile, name='sql_profile'),
+ url(r"^sql_select/$", views.sql_select, name="sql_select"),
+ url(r"^sql_explain/$", views.sql_explain, name="sql_explain"),
+ url(r"^sql_profile/$", views.sql_profile, name="sql_profile"),
]
def enable_instrumentation(self):
@@ -147,14 +152,16 @@ def generate_stats(self, request, response):
# The keys used to determine similar and duplicate queries.
def similar_key(query):
- return query['raw_sql']
+ return query["raw_sql"]
def duplicate_key(query):
- raw_params = () if query['raw_params'] is None else tuple(query['raw_params'])
+ raw_params = (
+ () if query["raw_params"] is None else tuple(query["raw_params"])
+ )
# saferepr() avoids problems because of unhashable types
# (e.g. lists) when used as dictionary keys.
# https://github.com/jazzband/django-debug-toolbar/issues/1091
- return (query['raw_sql'], saferepr(raw_params))
+ return (query["raw_sql"], saferepr(raw_params))
if self._queries:
width_ratio_tally = 0
@@ -172,7 +179,7 @@ def duplicate_key(query):
if nn > 2:
nn = 0
rgb[nn] = nc
- db['rgb_color'] = rgb
+ db["rgb_color"] = rgb
trans_ids = {}
trans_id = None
@@ -181,48 +188,51 @@ def duplicate_key(query):
query_similar[alias][similar_key(query)] += 1
query_duplicates[alias][duplicate_key(query)] += 1
- trans_id = query.get('trans_id')
+ trans_id = query.get("trans_id")
last_trans_id = trans_ids.get(alias)
if trans_id != last_trans_id:
if last_trans_id:
- self._queries[(i - 1)][1]['ends_trans'] = True
+ self._queries[(i - 1)][1]["ends_trans"] = True
trans_ids[alias] = trans_id
if trans_id:
- query['starts_trans'] = True
+ query["starts_trans"] = True
if trans_id:
- query['in_trans'] = True
-
- query['alias'] = alias
- if 'iso_level' in query:
- query['iso_level'] = get_isolation_level_display(query['vendor'],
- query['iso_level'])
- if 'trans_status' in query:
- query['trans_status'] = get_transaction_status_display(query['vendor'],
- query['trans_status'])
-
- query['form'] = SQLSelectForm(auto_id=None, initial=copy(query))
-
- if query['sql']:
- query['sql'] = reformat_sql(query['sql'])
- query['rgb_color'] = self._databases[alias]['rgb_color']
+ query["in_trans"] = True
+
+ query["alias"] = alias
+ if "iso_level" in query:
+ query["iso_level"] = get_isolation_level_display(
+ query["vendor"], query["iso_level"]
+ )
+ if "trans_status" in query:
+ query["trans_status"] = get_transaction_status_display(
+ query["vendor"], query["trans_status"]
+ )
+
+ query["form"] = SQLSelectForm(auto_id=None, initial=copy(query))
+
+ if query["sql"]:
+ query["sql"] = reformat_sql(query["sql"])
+ query["rgb_color"] = self._databases[alias]["rgb_color"]
try:
- query['width_ratio'] = (query['duration'] / self._sql_time) * 100
- query['width_ratio_relative'] = (
- 100.0 * query['width_ratio'] / (100.0 - width_ratio_tally))
+ query["width_ratio"] = (query["duration"] / self._sql_time) * 100
+ query["width_ratio_relative"] = (
+ 100.0 * query["width_ratio"] / (100.0 - width_ratio_tally)
+ )
except ZeroDivisionError:
- query['width_ratio'] = 0
- query['width_ratio_relative'] = 0
- query['start_offset'] = width_ratio_tally
- query['end_offset'] = query['width_ratio'] + query['start_offset']
- width_ratio_tally += query['width_ratio']
- query['stacktrace'] = render_stacktrace(query['stacktrace'])
+ query["width_ratio"] = 0
+ query["width_ratio_relative"] = 0
+ query["start_offset"] = width_ratio_tally
+ query["end_offset"] = query["width_ratio"] + query["start_offset"]
+ width_ratio_tally += query["width_ratio"]
+ query["stacktrace"] = render_stacktrace(query["stacktrace"])
i += 1
- query['trace_color'] = trace_colors[query['stacktrace']]
+ query["trace_color"] = trace_colors[query["stacktrace"]]
if trans_id:
- self._queries[(i - 1)][1]['ends_trans'] = True
+ self._queries[(i - 1)][1]["ends_trans"] = True
# Queries are similar / duplicates only if there's as least 2 of them.
# Also, to hide queries, we need to give all the duplicate groups an id
@@ -246,12 +256,13 @@ def duplicate_key(query):
for alias, query in self._queries:
try:
- (query["similar_count"], query["similar_color"]) = (
- query_similar_colors[alias][similar_key(query)]
- )
- (query["duplicate_count"], query["duplicate_color"]) = (
- query_duplicates_colors[alias][duplicate_key(query)]
- )
+ (query["similar_count"], query["similar_color"]) = query_similar_colors[
+ alias
+ ][similar_key(query)]
+ (
+ query["duplicate_count"],
+ query["duplicate_color"],
+ ) = query_duplicates_colors[alias][duplicate_key(query)]
except KeyError:
pass
@@ -266,14 +277,18 @@ def duplicate_key(query):
except KeyError:
pass
- self.record_stats({
- 'databases': sorted(self._databases.items(), key=lambda x: -x[1]['time_spent']),
- 'queries': [q for a, q in self._queries],
- 'sql_time': self._sql_time,
- })
+ self.record_stats(
+ {
+ "databases": sorted(
+ self._databases.items(), key=lambda x: -x[1]["time_spent"]
+ ),
+ "queries": [q for a, q in self._queries],
+ "sql_time": self._sql_time,
+ }
+ )
def generate_server_timing(self, request, response):
stats = self.get_stats()
- title = 'SQL {} queries'.format(len(stats.get('queries', [])))
- value = stats.get('sql_time', 0)
- self.record_server_timing('sql_time', title, value)
+ title = "SQL {} queries".format(len(stats.get("queries", [])))
+ value = stats.get("sql_time", 0)
+ self.record_server_timing("sql_time", title, value)
diff --git a/debug_toolbar/panels/sql/tracking.py b/debug_toolbar/panels/sql/tracking.py
index fe1de6af8..69e7ed8e0 100644
--- a/debug_toolbar/panels/sql/tracking.py
+++ b/debug_toolbar/panels/sql/tracking.py
@@ -14,6 +14,7 @@
class SQLQueryTriggered(Exception):
"""Thrown when template panel triggers a query"""
+
pass
@@ -36,7 +37,7 @@ def recording(self, v):
def wrap_cursor(connection, panel):
- if not hasattr(connection, '_djdt_cursor'):
+ if not hasattr(connection, "_djdt_cursor"):
connection._djdt_cursor = connection.cursor
def cursor(*args, **kwargs):
@@ -46,14 +47,16 @@ def cursor(*args, **kwargs):
# See:
# https://github.com/jazzband/django-debug-toolbar/pull/615
# https://github.com/jazzband/django-debug-toolbar/pull/896
- return state.Wrapper(connection._djdt_cursor(*args, **kwargs), connection, panel)
+ return state.Wrapper(
+ connection._djdt_cursor(*args, **kwargs), connection, panel
+ )
connection.cursor = cursor
return cursor
def unwrap_cursor(connection):
- if hasattr(connection, '_djdt_cursor'):
+ if hasattr(connection, "_djdt_cursor"):
del connection._djdt_cursor
del connection.cursor
@@ -63,6 +66,7 @@ class ExceptionCursorWrapper(object):
Wraps a cursor and raises an exception on any operation.
Used in Templates panel.
"""
+
def __init__(self, cursor, db, logger):
pass
@@ -89,7 +93,7 @@ def _quote_expr(self, element):
except DjangoUnicodeDecodeError:
return repr(element)
elif isinstance(element, six.binary_type):
- return '(binary data)'
+ return "(binary data)"
else:
return repr(element)
@@ -114,7 +118,7 @@ def _decode(self, param):
try:
return force_text(param, strings_only=not isinstance(param, CONVERT_TYPES))
except UnicodeDecodeError:
- return '(encoded string)'
+ return "(encoded string)"
def _record(self, method, sql, params):
start_time = time()
@@ -123,11 +127,11 @@ def _record(self, method, sql, params):
finally:
stop_time = time()
duration = (stop_time - start_time) * 1000
- if dt_settings.get_config()['ENABLE_STACKTRACES']:
+ if dt_settings.get_config()["ENABLE_STACKTRACES"]:
stacktrace = tidy_stacktrace(reversed(get_stack()))
else:
stacktrace = []
- _params = ''
+ _params = ""
try:
_params = json.dumps(self._decode(params))
except TypeError:
@@ -135,41 +139,44 @@ def _record(self, method, sql, params):
template_info = get_template_info()
- alias = getattr(self.db, 'alias', 'default')
+ alias = getattr(self.db, "alias", "default")
conn = self.db.connection
- vendor = getattr(conn, 'vendor', 'unknown')
+ vendor = getattr(conn, "vendor", "unknown")
params = {
- 'vendor': vendor,
- 'alias': alias,
- 'sql': self.db.ops.last_executed_query(
- self.cursor, sql, self._quote_params(params)),
- 'duration': duration,
- 'raw_sql': sql,
- 'params': _params,
- 'raw_params': params,
- 'stacktrace': stacktrace,
- 'start_time': start_time,
- 'stop_time': stop_time,
- 'is_slow': duration > dt_settings.get_config()['SQL_WARNING_THRESHOLD'],
- 'is_select': sql.lower().strip().startswith('select'),
- 'template_info': template_info,
+ "vendor": vendor,
+ "alias": alias,
+ "sql": self.db.ops.last_executed_query(
+ self.cursor, sql, self._quote_params(params)
+ ),
+ "duration": duration,
+ "raw_sql": sql,
+ "params": _params,
+ "raw_params": params,
+ "stacktrace": stacktrace,
+ "start_time": start_time,
+ "stop_time": stop_time,
+ "is_slow": duration > dt_settings.get_config()["SQL_WARNING_THRESHOLD"],
+ "is_select": sql.lower().strip().startswith("select"),
+ "template_info": template_info,
}
- if vendor == 'postgresql':
+ if vendor == "postgresql":
# If an erroneous query was ran on the connection, it might
# be in a state where checking isolation_level raises an
# exception.
try:
iso_level = conn.isolation_level
except conn.InternalError:
- iso_level = 'unknown'
- params.update({
- 'trans_id': self.logger.get_transaction_id(alias),
- 'trans_status': conn.get_transaction_status(),
- 'iso_level': iso_level,
- 'encoding': conn.encoding,
- })
+ iso_level = "unknown"
+ params.update(
+ {
+ "trans_id": self.logger.get_transaction_id(alias),
+ "trans_status": conn.get_transaction_status(),
+ "iso_level": iso_level,
+ "encoding": conn.encoding,
+ }
+ )
# We keep `sql` to maintain backwards compatibility
self.logger.record(**params)
diff --git a/debug_toolbar/panels/sql/utils.py b/debug_toolbar/panels/sql/utils.py
index 197e4849c..5babe15d2 100644
--- a/debug_toolbar/panels/sql/utils.py
+++ b/debug_toolbar/panels/sql/utils.py
@@ -9,30 +9,33 @@
class BoldKeywordFilter:
"""sqlparse filter to bold SQL keywords"""
+
def process(self, stream):
"""Process the token stream"""
for token_type, value in stream:
is_keyword = token_type in T.Keyword
if is_keyword:
- yield T.Text, ''
+ yield T.Text, ""
yield token_type, escape(value)
if is_keyword:
- yield T.Text, ''
+ yield T.Text, ""
def reformat_sql(sql):
stack = sqlparse.engine.FilterStack()
stack.preprocess.append(BoldKeywordFilter()) # add our custom filter
stack.postprocess.append(sqlparse.filters.SerializerUnicode()) # tokens -> strings
- return swap_fields(''.join(stack.run(sql)))
+ return swap_fields("".join(stack.run(sql)))
def swap_fields(sql):
- expr = r'SELECT (...........*?) FROM'
- subs = (r'SELECT '
- r'••• '
- r'\1 '
- r'FROM')
+ expr = r"SELECT (...........*?) FROM"
+ subs = (
+ r"SELECT "
+ r'••• '
+ r'\1 '
+ r"FROM"
+ )
return re.sub(expr, subs, sql)
@@ -41,11 +44,19 @@ def contrasting_color_generator():
Generate constrasting colors by varying most significant bit of RGB first,
and then vary subsequent bits systematically.
"""
+
def rgb_to_hex(rgb):
- return '#%02x%02x%02x' % tuple(rgb)
+ return "#%02x%02x%02x" % tuple(rgb)
- triples = [(1, 0, 0), (0, 1, 0), (0, 0, 1),
- (1, 1, 0), (0, 1, 1), (1, 0, 1), (1, 1, 1)]
+ triples = [
+ (1, 0, 0),
+ (0, 1, 0),
+ (0, 0, 1),
+ (1, 1, 0),
+ (0, 1, 1),
+ (1, 0, 1),
+ (1, 1, 1),
+ ]
n = 1 << 7
so_far = [[0, 0, 0]]
while True:
diff --git a/debug_toolbar/panels/sql/views.py b/debug_toolbar/panels/sql/views.py
index 47fca4280..4f17421c0 100644
--- a/debug_toolbar/panels/sql/views.py
+++ b/debug_toolbar/panels/sql/views.py
@@ -15,23 +15,23 @@ def sql_select(request):
form = SQLSelectForm(request.POST or None)
if form.is_valid():
- sql = form.cleaned_data['raw_sql']
- params = form.cleaned_data['params']
+ sql = form.cleaned_data["raw_sql"]
+ params = form.cleaned_data["params"]
cursor = form.cursor
cursor.execute(sql, params)
headers = [d[0] for d in cursor.description]
result = cursor.fetchall()
cursor.close()
context = {
- 'result': result,
- 'sql': form.reformat_sql(),
- 'duration': form.cleaned_data['duration'],
- 'headers': headers,
- 'alias': form.cleaned_data['alias'],
+ "result": result,
+ "sql": form.reformat_sql(),
+ "duration": form.cleaned_data["duration"],
+ "headers": headers,
+ "alias": form.cleaned_data["alias"],
}
# Using SimpleTemplateResponse avoids running global context processors.
- return SimpleTemplateResponse('debug_toolbar/panels/sql_select.html', context)
- return HttpResponseBadRequest('Form errors')
+ return SimpleTemplateResponse("debug_toolbar/panels/sql_select.html", context)
+ return HttpResponseBadRequest("Form errors")
@csrf_exempt
@@ -41,17 +41,17 @@ def sql_explain(request):
form = SQLSelectForm(request.POST or None)
if form.is_valid():
- sql = form.cleaned_data['raw_sql']
- params = form.cleaned_data['params']
+ sql = form.cleaned_data["raw_sql"]
+ params = form.cleaned_data["params"]
vendor = form.connection.vendor
cursor = form.cursor
- if vendor == 'sqlite':
+ if vendor == "sqlite":
# SQLite's EXPLAIN dumps the low-level opcodes generated for a query;
# EXPLAIN QUERY PLAN dumps a more human-readable summary
# See https://www.sqlite.org/lang_explain.html for details
cursor.execute("EXPLAIN QUERY PLAN %s" % (sql,), params)
- elif vendor == 'postgresql':
+ elif vendor == "postgresql":
cursor.execute("EXPLAIN ANALYZE %s" % (sql,), params)
else:
cursor.execute("EXPLAIN %s" % (sql,), params)
@@ -60,15 +60,15 @@ def sql_explain(request):
result = cursor.fetchall()
cursor.close()
context = {
- 'result': result,
- 'sql': form.reformat_sql(),
- 'duration': form.cleaned_data['duration'],
- 'headers': headers,
- 'alias': form.cleaned_data['alias'],
+ "result": result,
+ "sql": form.reformat_sql(),
+ "duration": form.cleaned_data["duration"],
+ "headers": headers,
+ "alias": form.cleaned_data["alias"],
}
# Using SimpleTemplateResponse avoids running global context processors.
- return SimpleTemplateResponse('debug_toolbar/panels/sql_explain.html', context)
- return HttpResponseBadRequest('Form errors')
+ return SimpleTemplateResponse("debug_toolbar/panels/sql_explain.html", context)
+ return HttpResponseBadRequest("Form errors")
@csrf_exempt
@@ -78,8 +78,8 @@ def sql_profile(request):
form = SQLSelectForm(request.POST or None)
if form.is_valid():
- sql = form.cleaned_data['raw_sql']
- params = form.cleaned_data['params']
+ sql = form.cleaned_data["raw_sql"]
+ params = form.cleaned_data["params"]
cursor = form.cursor
result = None
headers = None
@@ -90,7 +90,8 @@ def sql_profile(request):
cursor.execute("SET PROFILING=0") # Disable profiling
# The Query ID should always be 1 here but I'll subselect to get
# the last one just in case...
- cursor.execute("""
+ cursor.execute(
+ """
SELECT *
FROM information_schema.profiling
WHERE query_id = (
@@ -99,20 +100,23 @@ def sql_profile(request):
ORDER BY query_id DESC
LIMIT 1
)
-""")
+"""
+ )
headers = [d[0] for d in cursor.description]
result = cursor.fetchall()
except Exception:
- result_error = "Profiling is either not available or not supported by your database."
+ result_error = (
+ "Profiling is either not available or not supported by your database."
+ )
cursor.close()
context = {
- 'result': result,
- 'result_error': result_error,
- 'sql': form.reformat_sql(),
- 'duration': form.cleaned_data['duration'],
- 'headers': headers,
- 'alias': form.cleaned_data['alias'],
+ "result": result,
+ "result_error": result_error,
+ "sql": form.reformat_sql(),
+ "duration": form.cleaned_data["duration"],
+ "headers": headers,
+ "alias": form.cleaned_data["alias"],
}
# Using SimpleTemplateResponse avoids running global context processors.
- return SimpleTemplateResponse('debug_toolbar/panels/sql_profile.html', context)
- return HttpResponseBadRequest('Form errors')
+ return SimpleTemplateResponse("debug_toolbar/panels/sql_profile.html", context)
+ return HttpResponseBadRequest("Form errors")
diff --git a/debug_toolbar/panels/staticfiles.py b/debug_toolbar/panels/staticfiles.py
index cd400d7c9..10661908b 100644
--- a/debug_toolbar/panels/staticfiles.py
+++ b/debug_toolbar/panels/staticfiles.py
@@ -25,6 +25,7 @@ class StaticFile(object):
"""
Representing the different properties of a static file.
"""
+
def __init__(self, path):
self.path = path
@@ -39,10 +40,9 @@ def url(self):
class FileCollector(ThreadCollector):
-
def collect(self, path, thread=None):
# handle the case of {% static "admin/" %}
- if path.endswith('/'):
+ if path.endswith("/"):
return
super(FileCollector, self).collect(StaticFile(path), thread)
@@ -56,12 +56,12 @@ class DebugConfiguredStorage(LazyObject):
are resolved by using the {% static %} template tag (which uses the
`url` method).
"""
+
def _setup(self):
configured_storage_cls = get_storage_class(settings.STATICFILES_STORAGE)
class DebugStaticFilesStorage(configured_storage_cls):
-
def __init__(self, collector, *args, **kwargs):
super(DebugStaticFilesStorage, self).__init__(*args, **kwargs)
self.collector = collector
@@ -80,13 +80,16 @@ class StaticFilesPanel(panels.Panel):
"""
A panel to display the found staticfiles.
"""
- name = 'Static files'
- template = 'debug_toolbar/panels/staticfiles.html'
+
+ name = "Static files"
+ template = "debug_toolbar/panels/staticfiles.html"
@property
def title(self):
- return (_("Static files (%(num_found)s found, %(num_used)s used)") %
- {'num_found': self.num_found, 'num_used': self.num_used})
+ return _("Static files (%(num_found)s found, %(num_used)s used)") % {
+ "num_found": self.num_found,
+ "num_used": self.num_used,
+ }
def __init__(self, *args, **kwargs):
super(StaticFilesPanel, self).__init__(*args, **kwargs)
@@ -94,23 +97,27 @@ def __init__(self, *args, **kwargs):
self._paths = {}
def enable_instrumentation(self):
- storage.staticfiles_storage = staticfiles.staticfiles_storage = DebugConfiguredStorage()
+ storage.staticfiles_storage = (
+ staticfiles.staticfiles_storage
+ ) = DebugConfiguredStorage()
def disable_instrumentation(self):
- storage.staticfiles_storage = staticfiles.staticfiles_storage = _original_storage
+ storage.staticfiles_storage = (
+ staticfiles.staticfiles_storage
+ ) = _original_storage
@property
def num_used(self):
return len(self._paths[threading.currentThread()])
- nav_title = _('Static files')
+ nav_title = _("Static files")
@property
def nav_subtitle(self):
num_used = self.num_used
- return ungettext("%(num_used)s file used",
- "%(num_used)s files used",
- num_used) % {'num_used': num_used}
+ return ungettext(
+ "%(num_used)s file used", "%(num_used)s files used", num_used
+ ) % {"num_used": num_used}
def process_request(self, request):
collector.clear_collection()
@@ -119,14 +126,16 @@ def generate_stats(self, request, response):
used_paths = collector.get_collection()
self._paths[threading.currentThread()] = used_paths
- self.record_stats({
- 'num_found': self.num_found,
- 'num_used': self.num_used,
- 'staticfiles': used_paths,
- 'staticfiles_apps': self.get_staticfiles_apps(),
- 'staticfiles_dirs': self.get_staticfiles_dirs(),
- 'staticfiles_finders': self.get_staticfiles_finders(),
- })
+ self.record_stats(
+ {
+ "num_found": self.num_found,
+ "num_used": self.num_used,
+ "staticfiles": used_paths,
+ "staticfiles_apps": self.get_staticfiles_apps(),
+ "staticfiles_dirs": self.get_staticfiles_dirs(),
+ "staticfiles_finders": self.get_staticfiles_finders(),
+ }
+ )
def get_staticfiles_finders(self):
"""
@@ -137,13 +146,12 @@ def get_staticfiles_finders(self):
finders_mapping = OrderedDict()
for finder in finders.get_finders():
for path, finder_storage in finder.list([]):
- if getattr(finder_storage, 'prefix', None):
+ if getattr(finder_storage, "prefix", None):
prefixed_path = join(finder_storage.prefix, path)
else:
prefixed_path = path
finder_cls = finder.__class__
- finder_path = '.'.join([finder_cls.__module__,
- finder_cls.__name__])
+ finder_path = ".".join([finder_cls.__module__, finder_cls.__name__])
real_path = finder_storage.path(path)
payload = (prefixed_path, real_path)
finders_mapping.setdefault(finder_path, []).append(payload)
diff --git a/debug_toolbar/panels/templates/panel.py b/debug_toolbar/panels/templates/panel.py
index 56bd04ad5..15397dfe5 100644
--- a/debug_toolbar/panels/templates/panel.py
+++ b/debug_toolbar/panels/templates/panel.py
@@ -34,6 +34,7 @@
# Monkey-patch to store items added by template context processors. The
# overhead is sufficiently small to justify enabling it unconditionally.
+
@contextmanager
def _request_context_bind_template(self, template):
if self.template is not None:
@@ -41,12 +42,11 @@ def _request_context_bind_template(self, template):
self.template = template
# Set context processors according to the template engine's settings.
- processors = (template.engine.template_context_processors +
- self._processors)
+ processors = template.engine.template_context_processors + self._processors
self.context_processors = OrderedDict()
updates = {}
for processor in processors:
- name = '%s.%s' % (processor.__module__, processor.__name__)
+ name = "%s.%s" % (processor.__module__, processor.__name__)
context = processor(self.request)
self.context_processors[name] = context
updates.update(context)
@@ -67,6 +67,7 @@ class TemplatesPanel(Panel):
"""
A panel that lists all templates used during processing of a response.
"""
+
def __init__(self, *args, **kwargs):
super(TemplatesPanel, self).__init__(*args, **kwargs)
self.templates = []
@@ -82,18 +83,21 @@ def __init__(self, *args, **kwargs):
self.pformat_layers = []
def _store_template_info(self, sender, **kwargs):
- template, context = kwargs['template'], kwargs['context']
+ template, context = kwargs["template"], kwargs["context"]
# Skip templates that we are generating through the debug toolbar.
- if (isinstance(template.name, six.string_types) and (
- template.name.startswith('debug_toolbar/') or
- template.name.startswith(
- tuple(self.toolbar.config['SKIP_TEMPLATE_PREFIXES'])))):
+ is_debug_toolbar_template = isinstance(template.name, six.string_types) and (
+ template.name.startswith("debug_toolbar/")
+ or template.name.startswith(
+ tuple(self.toolbar.config["SKIP_TEMPLATE_PREFIXES"])
+ )
+ )
+ if is_debug_toolbar_template:
return
context_list = []
for context_layer in context.dicts:
- if hasattr(context_layer, 'items') and context_layer:
+ if hasattr(context_layer, "items") and context_layer:
# Refs GitHub issue #910
# If we can find this layer in our pseudo-cache then find the
# matching prettified version in the associated list.
@@ -109,30 +113,36 @@ def _store_template_info(self, sender, **kwargs):
# unicode representation and the request data is
# already made available from the Request panel.
if isinstance(value, http.HttpRequest):
- temp_layer[key] = '<
', - 'RENDER_PANELS': None, - 'RESULTS_CACHE_SIZE': 10, - 'ROOT_TAG_EXTRA_ATTRS': '', - 'SHOW_COLLAPSED': False, - 'SHOW_TOOLBAR_CALLBACK': 'debug_toolbar.middleware.show_toolbar', + "DISABLE_PANELS": {"debug_toolbar.panels.redirects.RedirectsPanel"}, + "INSERT_BEFORE": "", + "RENDER_PANELS": None, + "RESULTS_CACHE_SIZE": 10, + "ROOT_TAG_EXTRA_ATTRS": "", + "SHOW_COLLAPSED": False, + "SHOW_TOOLBAR_CALLBACK": "debug_toolbar.middleware.show_toolbar", # Panel options - 'EXTRA_SIGNALS': [], - 'ENABLE_STACKTRACES': True, - 'HIDE_IN_STACKTRACES': ( - 'socketserver' if six.PY3 else 'SocketServer', - 'threading', - 'wsgiref', - 'debug_toolbar', - 'django.db', - 'django.core.handlers', - 'django.core.servers', - 'django.utils.decorators', - 'django.utils.deprecation', - 'django.utils.functional', + "EXTRA_SIGNALS": [], + "ENABLE_STACKTRACES": True, + "HIDE_IN_STACKTRACES": ( + "socketserver" if six.PY3 else "SocketServer", + "threading", + "wsgiref", + "debug_toolbar", + "django.db", + "django.core.handlers", + "django.core.servers", + "django.utils.decorators", + "django.utils.deprecation", + "django.utils.functional", ), - 'PROFILER_MAX_DEPTH': 10, - 'SHOW_TEMPLATE_CONTEXT': True, - 'SKIP_TEMPLATE_PREFIXES': ( - 'django/forms/widgets/', - 'admin/widgets/', - ), - 'SQL_WARNING_THRESHOLD': 500, # milliseconds + "PROFILER_MAX_DEPTH": 10, + "SHOW_TEMPLATE_CONTEXT": True, + "SKIP_TEMPLATE_PREFIXES": ("django/forms/widgets/", "admin/widgets/"), + "SQL_WARNING_THRESHOLD": 500, # milliseconds } @lru_cache() def get_config(): - USER_CONFIG = getattr(settings, 'DEBUG_TOOLBAR_CONFIG', {}) + USER_CONFIG = getattr(settings, "DEBUG_TOOLBAR_CONFIG", {}) # Backward-compatibility for 1.0, remove in 2.0. _RENAMED_CONFIG = { - 'RESULTS_STORE_SIZE': 'RESULTS_CACHE_SIZE', - 'ROOT_TAG_ATTRS': 'ROOT_TAG_EXTRA_ATTRS', - 'HIDDEN_STACKTRACE_MODULES': 'HIDE_IN_STACKTRACES' + "RESULTS_STORE_SIZE": "RESULTS_CACHE_SIZE", + "ROOT_TAG_ATTRS": "ROOT_TAG_EXTRA_ATTRS", + "HIDDEN_STACKTRACE_MODULES": "HIDE_IN_STACKTRACES", } for old_name, new_name in _RENAMED_CONFIG.items(): if old_name in USER_CONFIG: warnings.warn( "%r was renamed to %r. Update your DEBUG_TOOLBAR_CONFIG " - "setting." % (old_name, new_name), DeprecationWarning) + "setting." % (old_name, new_name), + DeprecationWarning, + ) USER_CONFIG[new_name] = USER_CONFIG.pop(old_name) - if 'HIDE_DJANGO_SQL' in USER_CONFIG: + if "HIDE_DJANGO_SQL" in USER_CONFIG: warnings.warn( - "HIDE_DJANGO_SQL was removed. Update your " - "DEBUG_TOOLBAR_CONFIG setting.", DeprecationWarning) - USER_CONFIG.pop('HIDE_DJANGO_SQL') + "HIDE_DJANGO_SQL was removed. Update your " "DEBUG_TOOLBAR_CONFIG setting.", + DeprecationWarning, + ) + USER_CONFIG.pop("HIDE_DJANGO_SQL") - if 'TAG' in USER_CONFIG: + if "TAG" in USER_CONFIG: warnings.warn( "TAG was replaced by INSERT_BEFORE. Update your " - "DEBUG_TOOLBAR_CONFIG setting.", DeprecationWarning) - USER_CONFIG['INSERT_BEFORE'] = '%s>' % USER_CONFIG.pop('TAG') + "DEBUG_TOOLBAR_CONFIG setting.", + DeprecationWarning, + ) + USER_CONFIG["INSERT_BEFORE"] = "%s>" % USER_CONFIG.pop("TAG") CONFIG = CONFIG_DEFAULTS.copy() CONFIG.update(USER_CONFIG) - if 'INTERCEPT_REDIRECTS' in USER_CONFIG: + if "INTERCEPT_REDIRECTS" in USER_CONFIG: warnings.warn( "INTERCEPT_REDIRECTS is deprecated. Please use the " "DISABLE_PANELS config in the " - "DEBUG_TOOLBAR_CONFIG setting.", DeprecationWarning) - if USER_CONFIG['INTERCEPT_REDIRECTS']: - if 'debug_toolbar.panels.redirects.RedirectsPanel' \ - in CONFIG['DISABLE_PANELS']: + "DEBUG_TOOLBAR_CONFIG setting.", + DeprecationWarning, + ) + if USER_CONFIG["INTERCEPT_REDIRECTS"]: + if ( + "debug_toolbar.panels.redirects.RedirectsPanel" + in CONFIG["DISABLE_PANELS"] + ): # RedirectsPanel should be enabled try: - CONFIG['DISABLE_PANELS'].remove( - 'debug_toolbar.panels.redirects.RedirectsPanel' + CONFIG["DISABLE_PANELS"].remove( + "debug_toolbar.panels.redirects.RedirectsPanel" ) except KeyError: # We wanted to remove it, but it didn't exist. This is fine pass - elif 'debug_toolbar.panels.redirects.RedirectsPanel' \ - not in CONFIG['DISABLE_PANELS']: + elif ( + "debug_toolbar.panels.redirects.RedirectsPanel" + not in CONFIG["DISABLE_PANELS"] + ): # RedirectsPanel should be disabled - CONFIG['DISABLE_PANELS'].add( - 'debug_toolbar.panels.redirects.RedirectsPanel' + CONFIG["DISABLE_PANELS"].add( + "debug_toolbar.panels.redirects.RedirectsPanel" ) return CONFIG PANELS_DEFAULTS = [ - 'debug_toolbar.panels.versions.VersionsPanel', - 'debug_toolbar.panels.timer.TimerPanel', - 'debug_toolbar.panels.settings.SettingsPanel', - 'debug_toolbar.panels.headers.HeadersPanel', - 'debug_toolbar.panels.request.RequestPanel', - 'debug_toolbar.panels.sql.SQLPanel', - 'debug_toolbar.panels.staticfiles.StaticFilesPanel', - 'debug_toolbar.panels.templates.TemplatesPanel', - 'debug_toolbar.panels.cache.CachePanel', - 'debug_toolbar.panels.signals.SignalsPanel', - 'debug_toolbar.panels.logging.LoggingPanel', - 'debug_toolbar.panels.redirects.RedirectsPanel', + "debug_toolbar.panels.versions.VersionsPanel", + "debug_toolbar.panels.timer.TimerPanel", + "debug_toolbar.panels.settings.SettingsPanel", + "debug_toolbar.panels.headers.HeadersPanel", + "debug_toolbar.panels.request.RequestPanel", + "debug_toolbar.panels.sql.SQLPanel", + "debug_toolbar.panels.staticfiles.StaticFilesPanel", + "debug_toolbar.panels.templates.TemplatesPanel", + "debug_toolbar.panels.cache.CachePanel", + "debug_toolbar.panels.signals.SignalsPanel", + "debug_toolbar.panels.logging.LoggingPanel", + "debug_toolbar.panels.redirects.RedirectsPanel", ] @@ -130,36 +138,26 @@ def get_panels(): else: # Backward-compatibility for 1.0, remove in 2.0. _RENAMED_PANELS = { - 'debug_toolbar.panels.version.VersionDebugPanel': - 'debug_toolbar.panels.versions.VersionsPanel', - 'debug_toolbar.panels.timer.TimerDebugPanel': - 'debug_toolbar.panels.timer.TimerPanel', - 'debug_toolbar.panels.settings_vars.SettingsDebugPanel': - 'debug_toolbar.panels.settings.SettingsPanel', - 'debug_toolbar.panels.headers.HeaderDebugPanel': - 'debug_toolbar.panels.headers.HeadersPanel', - 'debug_toolbar.panels.request_vars.RequestVarsDebugPanel': - 'debug_toolbar.panels.request.RequestPanel', - 'debug_toolbar.panels.sql.SQLDebugPanel': - 'debug_toolbar.panels.sql.SQLPanel', - 'debug_toolbar.panels.template.TemplateDebugPanel': - 'debug_toolbar.panels.templates.TemplatesPanel', - 'debug_toolbar.panels.cache.CacheDebugPanel': - 'debug_toolbar.panels.cache.CachePanel', - 'debug_toolbar.panels.signals.SignalDebugPanel': - 'debug_toolbar.panels.signals.SignalsPanel', - 'debug_toolbar.panels.logger.LoggingDebugPanel': - 'debug_toolbar.panels.logging.LoggingPanel', - 'debug_toolbar.panels.redirects.InterceptRedirectsDebugPanel': - 'debug_toolbar.panels.redirects.RedirectsPanel', - 'debug_toolbar.panels.profiling.ProfilingDebugPanel': - 'debug_toolbar.panels.profiling.ProfilingPanel', + "debug_toolbar.panels.version.VersionDebugPanel": "debug_toolbar.panels.versions.VersionsPanel", # noqa + "debug_toolbar.panels.timer.TimerDebugPanel": "debug_toolbar.panels.timer.TimerPanel", # noqa + "debug_toolbar.panels.settings_vars.SettingsDebugPanel": "debug_toolbar.panels.settings.SettingsPanel", # noqa + "debug_toolbar.panels.headers.HeaderDebugPanel": "debug_toolbar.panels.headers.HeadersPanel", # noqa + "debug_toolbar.panels.request_vars.RequestVarsDebugPanel": "debug_toolbar.panels.request.RequestPanel", # noqa + "debug_toolbar.panels.sql.SQLDebugPanel": "debug_toolbar.panels.sql.SQLPanel", # noqa + "debug_toolbar.panels.template.TemplateDebugPanel": "debug_toolbar.panels.templates.TemplatesPanel", # noqa + "debug_toolbar.panels.cache.CacheDebugPanel": "debug_toolbar.panels.cache.CachePanel", # noqa + "debug_toolbar.panels.signals.SignalDebugPanel": "debug_toolbar.panels.signals.SignalsPanel", # noqa + "debug_toolbar.panels.logger.LoggingDebugPanel": "debug_toolbar.panels.logging.LoggingPanel", # noqa + "debug_toolbar.panels.redirects.InterceptRedirectsDebugPanel": "debug_toolbar.panels.redirects.RedirectsPanel", # noqa + "debug_toolbar.panels.profiling.ProfilingDebugPanel": "debug_toolbar.panels.profiling.ProfilingPanel", # noqa } for index, old_panel in enumerate(PANELS): new_panel = _RENAMED_PANELS.get(old_panel) if new_panel is not None: warnings.warn( "%r was renamed to %r. Update your DEBUG_TOOLBAR_PANELS " - "setting." % (old_panel, new_panel), DeprecationWarning) + "setting." % (old_panel, new_panel), + DeprecationWarning, + ) PANELS[index] = new_panel return PANELS diff --git a/debug_toolbar/static/debug_toolbar/js/redirect.js b/debug_toolbar/static/debug_toolbar/js/redirect.js new file mode 100644 index 000000000..f73d9e52b --- /dev/null +++ b/debug_toolbar/static/debug_toolbar/js/redirect.js @@ -0,0 +1 @@ +document.getElementById('redirect_to').focus(); diff --git a/debug_toolbar/templates/debug_toolbar/base.html b/debug_toolbar/templates/debug_toolbar/base.html index 3d4740c60..d10740b0f 100644 --- a/debug_toolbar/templates/debug_toolbar/base.html +++ b/debug_toolbar/templates/debug_toolbar/base.html @@ -1,7 +1,7 @@ {% load i18n %}{% load static %} - +
{% trans "No SQL queries were recorded during this request." %}
{% endif %} - + diff --git a/debug_toolbar/templates/debug_toolbar/panels/sql_explain.html b/debug_toolbar/templates/debug_toolbar/panels/sql_explain.html index c7651e08d..0c6124c41 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/sql_explain.html +++ b/debug_toolbar/templates/debug_toolbar/panels/sql_explain.html @@ -34,4 +34,4 @@- + diff --git a/debug_toolbar/templates/debug_toolbar/panels/sql_profile.html b/debug_toolbar/templates/debug_toolbar/panels/sql_profile.html index 5a07fee88..8b1f711cf 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/sql_profile.html +++ b/debug_toolbar/templates/debug_toolbar/panels/sql_profile.html @@ -41,4 +41,4 @@
- + diff --git a/debug_toolbar/templates/debug_toolbar/panels/sql_select.html b/debug_toolbar/templates/debug_toolbar/panels/sql_select.html index 75b1a8458..6c3765163 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/sql_select.html +++ b/debug_toolbar/templates/debug_toolbar/panels/sql_select.html @@ -38,4 +38,4 @@
- + diff --git a/debug_toolbar/templates/debug_toolbar/panels/timer.html b/debug_toolbar/templates/debug_toolbar/panels/timer.html index 2aa039af4..36c99db82 100644 --- a/debug_toolbar/templates/debug_toolbar/panels/timer.html +++ b/debug_toolbar/templates/debug_toolbar/panels/timer.html @@ -41,4 +41,4 @@
- + diff --git a/debug_toolbar/templates/debug_toolbar/redirect.html b/debug_toolbar/templates/debug_toolbar/redirect.html index 365fb482a..761712287 100644 --- a/debug_toolbar/templates/debug_toolbar/redirect.html +++ b/debug_toolbar/templates/debug_toolbar/redirect.html @@ -1,4 +1,4 @@ -{% load i18n %} +{% load i18n static %}
@@ -9,8 +9,6 @@
{% trans "The Django Debug Toolbar has intercepted a redirect to the above URL for debug viewing purposes. You can click the above link to continue with the redirect as normal." %}
- +