import time from django.test.signals import template_rendered from django.conf import settings from django.db import connection from django.utils.encoding import force_unicode from django.utils.safestring import mark_safe TEMPLATE = """
+
""" # Monkeypatch instrumented test renderer from django.test.utils - we could use # django.test.utils.setup_test_environment for this but that would also set up # e-mail interception, which we don't want from django.test.utils import instrumented_test_render from django.template import Template, Context if Template.render != instrumented_test_render: Template.original_render = Template.render Template.render = instrumented_test_render # MONSTER monkey-patch old_template_init = Template.__init__ def new_template_init(self, template_string, origin=None, name=''): old_template_init(self, template_string, origin, name) self.origin = origin Template.__init__ = new_template_init class DebugFooter: def process_request(self, request): self.time_started = time.time() self.templates_used = [] self.contexts_used = [] self.sql_offset_start = len(connection.queries) template_rendered.connect(self._storeRenderedTemplates) def process_response(self, request, response): # Only include debug info for text/html pages not accessed via Ajax if 'text/html' not in response['Content-Type']: return response if request.is_ajax(): return response if not settings.DEBUG: return response if response.status_code != 200: return response templates = [] for t in self.templates_used: if t.origin and t.origin.name: templates.append( (t.name, _txtmate(t.origin.name,t.origin.name) ) ) else: templates.append( (t.name, "no origin") ) sql_queries = connection.queries[self.sql_offset_start:] # Reformat sql queries a bit sql_total = 0.0 sql_counts = {} for query in sql_queries: raw_sql = query['sql'] query['sql'] = reformat_sql(query['sql']) sql_total += float(query['time']) count = sql_counts.get(raw_sql,0) + 1 sql_counts[raw_sql] = count if count > 1: query['style'] = mark_safe(' style="background:#ff0000;"') query['count'] = mark_safe('

duplicate query count=%s

' % count) else: query['style'] = '' query['count'] = '' from django.core.urlresolvers import resolve view_func, args, kwargs = resolve(request.META['PATH_INFO']) #@UnusedVariable view = '%s.%s' % (view_func.__module__, view_func.__name__) vf = view_func breaker = 10 while not hasattr(vf,'func_code'): if hasattr(vf,'view_func'): vf = vf.view_func else: break # somethings wrong about the assumptions of the decorator breaker = breaker - 1 if breaker < 0: break if hasattr(vf,'func_code'): co = vf.func_code filename = co.co_filename lineno = co.co_firstlineno view = _txtmate(co.co_filename,view,co.co_firstlineno) debug_content = Template(TEMPLATE).render(Context({ 'server_time': time.time() - self.time_started, 'templates': templates, 'sql': sql_queries, 'sql_total': sql_total, 'num_queries' : len(sql_queries), 'template_dirs': settings.TEMPLATE_DIRS, 'view': view })) content = response.content response.content = force_unicode(content).replace('', debug_content) return response def _storeRenderedTemplates(self, **kwargs): #signal=signal, sender=sender, template=template, context=context): template = kwargs.get('template') if(template): self.templates_used.append(template) context = kwargs.get('context') if(context): self.contexts_used.append(context) def reformat_sql(sql): sql = sql.replace('`,`', '`, `') sql = sql.replace('` FROM `', '` \n FROM `') sql = sql.replace('` WHERE ', '` \n WHERE ') sql = sql.replace(' ORDER BY ', ' \n ORDER BY ') return sql def _txtmate(path,name,lineno=""): return mark_safe("%s" % (path,lineno,name))