Permalink
Browse files

Update cache panel for django 1.3 by implementing every method and pr…

…oviding a cache backend instead of monkeypatching. Also update the template to match SQL Panel a little more.
  • Loading branch information...
1 parent 8cb8aba commit 9aa062bb6c4318aa81c202003ea902249c0071d1 @diox diox committed Apr 6, 2011
View
4 debug_toolbar/media/debug_toolbar/css/toolbar.css
@@ -357,6 +357,10 @@
text-align: left;
}
+#djDebug .djCacheHideStacktraceDiv tbody th {
+ text-align: left;
+}
+
#djDebug .djSqlExplain td {
white-space: pre;
}
View
2 debug_toolbar/media/debug_toolbar/css/toolbar.min.css
@@ -1 +1 @@
-#djDebug{color:#000;background:#FFF;}#djDebug,#djDebug div,#djDebug span,#djDebug applet,#djDebug object,#djDebug iframe,#djDebug h1,#djDebug h2,#djDebug h3,#djDebug h4,#djDebug h5,#djDebug h6,#djDebug p,#djDebug blockquote,#djDebug pre,#djDebug a,#djDebug abbr,#djDebug acronym,#djDebug address,#djDebug big,#djDebug cite,#djDebug code,#djDebug del,#djDebug dfn,#djDebug em,#djDebug font,#djDebug img,#djDebug ins,#djDebug kbd,#djDebug q,#djDebug s,#djDebug samp,#djDebug small,#djDebug strike,#djDebug strong,#djDebug sub,#djDebug sup,#djDebug tt,#djDebug var,#djDebug b,#djDebug u,#djDebug i,#djDebug center,#djDebug dl,#djDebug dt,#djDebug dd,#djDebug ol,#djDebug ul,#djDebug li,#djDebug fieldset,#djDebug form,#djDebug label,#djDebug legend,#djDebug table,#djDebug caption,#djDebug tbody,#djDebug tfoot,#djDebug thead,#djDebug tr,#djDebug th,#djDebug td{margin:0;padding:0;border:0;outline:0;font-size:12px;line-height:1.5em;color:#000;vertical-align:baseline;background:transparent;font-family:sans-serif;text-align:left;}#djDebug #djDebugToolbar{background:#111;width:200px;z-index:100000000;position:fixed;top:0;bottom:0;right:0;opacity:.9;}#djDebug #djDebugToolbar small{color:#999;}#djDebug #djDebugToolbar ul{margin:0;padding:0;list-style:none;}#djDebug #djDebugToolbar li{border-bottom:1px solid #222;color:#fff;display:block;font-weight:bold;float:none;margin:0;padding:0;position:relative;width:auto;}#djDebug #djDebugToolbar li>a,#djDebug #djDebugToolbar li>div.contentless{font-weight:normal;font-style:normal;text-decoration:none;display:block;font-size:16px;padding:10px 10px 5px 25px;color:#fff;}#djDebug #djDebugToolbar li a:hover{color:#111;background-color:#ffc;}#djDebug #djDebugToolbar li.active{background-image:url(../img/indicator.png);background-repeat:no-repeat;background-position:left center;background-color:#333;padding-left:10px;}#djDebug #djDebugToolbar li.active a:hover{color:#b36a60;background-color:transparent;}#djDebug #djDebugToolbar li small{font-size:12px;color:#999;font-style:normal;text-decoration:none;font-variant:small-caps;}#djDebug #djDebugToolbarHandle{position:fixed;background:#fff;border:1px solid #111;top:30px;right:0;z-index:100000000;opacity:.75;}#djDebug a#djShowToolBarButton{display:block;height:75px;width:30px;border-right:none;border-bottom:4px solid #fff;border-top:4px solid #fff;border-left:4px solid #fff;color:#fff;font-size:10px;font-weight:bold;text-decoration:none;text-align:center;text-indent:-999999px;background:#000 url(../img/djdt_vertical.png) no-repeat left center;opacity:.5;}#djDebug a#djShowToolBarButton:hover{background-color:#111;padding-right:6px;border-top-color:#FFE761;border-left-color:#FFE761;border-bottom-color:#FFE761;opacity:1.0;}#djDebug code{display:block;font-family:Consolas,Monaco,"Bitstream Vera Sans Mono","Lucida Console",monospace;white-space:pre;overflow:auto;}#djDebug tr.djDebugOdd{background-color:#f5f5f5;}#djDebug .panelContent{display:none;position:fixed;margin:0;top:0;right:200px;bottom:0;left:0;background-color:#eee;color:#666;z-index:100000000;}#djDebug .panelContent>div{border-bottom:1px solid #ddd;}#djDebug .djDebugPanelTitle{position:absolute;background-color:#ffc;color:#666;padding-left:20px;top:0;right:0;left:0;height:50px;}#djDebug .djDebugPanelTitle code{display:inline;font-size:inherit;}#djDebug .djDebugPanelContent{position:absolute;top:50px;right:0;bottom:0;left:0;height:auto;padding:0 0 0 20px;}#djDebug .djDebugPanelContent .scroll{height:100%;overflow:auto;display:block;padding:0 10px 0 0;}#djDebug h3{font-size:24px;font-weight:normal;line-height:50px;}#djDebug h4{font-size:20px;font-weight:bold;margin-top:.8em;}#djDebug .panelContent table{border:1px solid #ccc;border-collapse:collapse;width:100%;background-color:#fff;display:block;margin-top:.8em;overflow:auto;}#djDebug .panelContent tbody td,#djDebug .panelContent tbody th{vertical-align:top;padding:2px 3px;}#djDebug .panelContent thead th{padding:1px 6px 1px 3px;text-align:left;font-weight:bold;font-size:14px;}#djDebug .panelContent tbody th{width:12em;text-align:right;color:#666;padding-right:.5em;}#djDebug .djTemplateHideContextDiv{background-color:#fff;}#djDebug .panelContent .djDebugClose{text-indent:-9999999px;display:block;position:absolute;top:4px;right:15px;height:40px;width:40px;background:url(../img/close.png) no-repeat center center;}#djDebug .panelContent .djDebugClose:hover{background-image:url(../img/close_hover.png);}#djDebug .panelContent .djDebugClose.djDebugBack{background-image:url(../img/back.png);}#djDebug .panelContent .djDebugClose.djDebugBack:hover{background-image:url(../img/back_hover.png);}#djDebug .panelContent dt,#djDebug .panelContent dd{display:block;}#djDebug .panelContent dt{margin-top:.75em;}#djDebug .panelContent dd{margin-left:10px;}#djDebug a.toggleTemplate{padding:4px;background-color:#bbb;-moz-border-radius:3px;-webkit-border-radius:3px;}#djDebug a.toggleTemplate:hover{padding:4px;background-color:#444;color:#ffe761;-moz-border-radius:3px;-webkit-border-radius:3px;}#djDebug a.djTemplateShowContext,#djDebug a.djTemplateShowContext span.toggleArrow{color:#999;}#djDebug a.djTemplateShowContext:hover,#djDebug a.djTemplateShowContext:hover span.toggleArrow{color:#000;cursor:pointer;}#djDebug .djDebugSqlWrap{position:relative;}#djDebug .djDebugSql{z-index:100000002;}#djDebug .djSQLHideStacktraceDiv tbody th{text-align:left;}#djDebug .djSqlExplain td{white-space:pre;}#djDebug span.djDebugLineChart{background-color:#777;height:3px;position:absolute;bottom:0;top:0;left:0;display:block;z-index:1000000001;}#djDebug span.djDebugLineChartWarning{background-color:#900;}#djDebug .highlight{color:#000;}#djDebug .highlight .err{color:#000;}#djDebug .highlight .g{color:#000;}#djDebug .highlight .k{color:#000;font-weight:bold;}#djDebug .highlight .o{color:#000;}#djDebug .highlight .n{color:#000;}#djDebug .highlight .mi{color:#000;font-weight:bold;}#djDebug .highlight .l{color:#000;}#djDebug .highlight .x{color:#000;}#djDebug .highlight .p{color:#000;}#djDebug .highlight .m{color:#000;font-weight:bold;}#djDebug .highlight .s{color:#333;}#djDebug .highlight .w{color:#888;}#djDebug .highlight .il{color:#000;font-weight:bold;}#djDebug .highlight .na{color:#333;}#djDebug .highlight .nt{color:#000;font-weight:bold;}#djDebug .highlight .nv{color:#333;}#djDebug .highlight .s2{color:#333;}#djDebug .highlight .cp{color:#333;}
+#djDebug{color:#000;background:#FFF;}#djDebug,#djDebug div,#djDebug span,#djDebug applet,#djDebug object,#djDebug iframe,#djDebug h1,#djDebug h2,#djDebug h3,#djDebug h4,#djDebug h5,#djDebug h6,#djDebug p,#djDebug blockquote,#djDebug pre,#djDebug a,#djDebug abbr,#djDebug acronym,#djDebug address,#djDebug big,#djDebug cite,#djDebug code,#djDebug del,#djDebug dfn,#djDebug em,#djDebug font,#djDebug img,#djDebug ins,#djDebug kbd,#djDebug q,#djDebug s,#djDebug samp,#djDebug small,#djDebug strike,#djDebug strong,#djDebug sub,#djDebug sup,#djDebug tt,#djDebug var,#djDebug b,#djDebug u,#djDebug i,#djDebug center,#djDebug dl,#djDebug dt,#djDebug dd,#djDebug ol,#djDebug ul,#djDebug li,#djDebug fieldset,#djDebug form,#djDebug label,#djDebug legend,#djDebug table,#djDebug caption,#djDebug tbody,#djDebug tfoot,#djDebug thead,#djDebug tr,#djDebug th,#djDebug td{margin:0;padding:0;border:0;outline:0;font-size:12px;line-height:1.5em;color:#000;vertical-align:baseline;background:transparent;font-family:sans-serif;text-align:left;}#djDebug #djDebugToolbar{background:#111;width:200px;z-index:100000000;position:fixed;top:0;bottom:0;right:0;opacity:.9;}#djDebug #djDebugToolbar small{color:#999;}#djDebug #djDebugToolbar ul{margin:0;padding:0;list-style:none;}#djDebug #djDebugToolbar li{border-bottom:1px solid #222;color:#fff;display:block;font-weight:bold;float:none;margin:0;padding:0;position:relative;width:auto;}#djDebug #djDebugToolbar li>a,#djDebug #djDebugToolbar li>div.contentless{font-weight:normal;font-style:normal;text-decoration:none;display:block;font-size:16px;padding:10px 10px 5px 25px;color:#fff;}#djDebug #djDebugToolbar li a:hover{color:#111;background-color:#ffc;}#djDebug #djDebugToolbar li.active{background-image:url(../img/indicator.png);background-repeat:no-repeat;background-position:left center;background-color:#333;padding-left:10px;}#djDebug #djDebugToolbar li.active a:hover{color:#b36a60;background-color:transparent;}#djDebug #djDebugToolbar li small{font-size:12px;color:#999;font-style:normal;text-decoration:none;font-variant:small-caps;}#djDebug #djDebugToolbarHandle{position:fixed;background:#fff;border:1px solid #111;top:30px;right:0;z-index:100000000;opacity:.75;}#djDebug a#djShowToolBarButton{display:block;height:75px;width:30px;border-right:none;border-bottom:4px solid #fff;border-top:4px solid #fff;border-left:4px solid #fff;color:#fff;font-size:10px;font-weight:bold;text-decoration:none;text-align:center;text-indent:-999999px;background:#000 url(../img/djdt_vertical.png) no-repeat left center;opacity:.5;}#djDebug a#djShowToolBarButton:hover{background-color:#111;padding-right:6px;border-top-color:#FFE761;border-left-color:#FFE761;border-bottom-color:#FFE761;opacity:1.0;}#djDebug code{display:block;font-family:Consolas,Monaco,"Bitstream Vera Sans Mono","Lucida Console",monospace;white-space:pre;overflow:auto;}#djDebug tr.djDebugOdd{background-color:#f5f5f5;}#djDebug .panelContent{display:none;position:fixed;margin:0;top:0;right:200px;bottom:0;left:0;background-color:#eee;color:#666;z-index:100000000;}#djDebug .panelContent>div{border-bottom:1px solid #ddd;}#djDebug .djDebugPanelTitle{position:absolute;background-color:#ffc;color:#666;padding-left:20px;top:0;right:0;left:0;height:50px;}#djDebug .djDebugPanelTitle code{display:inline;font-size:inherit;}#djDebug .djDebugPanelContent{position:absolute;top:50px;right:0;bottom:0;left:0;height:auto;padding:0 0 0 20px;}#djDebug .djDebugPanelContent .scroll{height:100%;overflow:auto;display:block;padding:0 10px 0 0;}#djDebug h3{font-size:24px;font-weight:normal;line-height:50px;}#djDebug h4{font-size:20px;font-weight:bold;margin-top:.8em;}#djDebug .panelContent table{border:1px solid #ccc;border-collapse:collapse;width:100%;background-color:#fff;display:block;margin-top:.8em;overflow:auto;}#djDebug .panelContent tbody td,#djDebug .panelContent tbody th{vertical-align:top;padding:2px 3px;}#djDebug .panelContent thead th{padding:1px 6px 1px 3px;text-align:left;font-weight:bold;font-size:14px;}#djDebug .panelContent tbody th{width:12em;text-align:right;color:#666;padding-right:.5em;}#djDebug .djTemplateHideContextDiv{background-color:#fff;}#djDebug .panelContent .djDebugClose{text-indent:-9999999px;display:block;position:absolute;top:4px;right:15px;height:40px;width:40px;background:url(../img/close.png) no-repeat center center;}#djDebug .panelContent .djDebugClose:hover{background-image:url(../img/close_hover.png);}#djDebug .panelContent .djDebugClose.djDebugBack{background-image:url(../img/back.png);}#djDebug .panelContent .djDebugClose.djDebugBack:hover{background-image:url(../img/back_hover.png);}#djDebug .panelContent dt,#djDebug .panelContent dd{display:block;}#djDebug .panelContent dt{margin-top:.75em;}#djDebug .panelContent dd{margin-left:10px;}#djDebug a.toggleTemplate{padding:4px;background-color:#bbb;-moz-border-radius:3px;-webkit-border-radius:3px;}#djDebug a.toggleTemplate:hover{padding:4px;background-color:#444;color:#ffe761;-moz-border-radius:3px;-webkit-border-radius:3px;}#djDebug a.djTemplateShowContext,#djDebug a.djTemplateShowContext span.toggleArrow{color:#999;}#djDebug a.djTemplateShowContext:hover,#djDebug a.djTemplateShowContext:hover span.toggleArrow{color:#000;cursor:pointer;}#djDebug .djDebugSqlWrap{position:relative;}#djDebug .djDebugSql{z-index:100000002;}#djDebug .djSQLHideStacktraceDiv tbody th{text-align:left;}#djDebug .djCacheHideStacktraceDiv tbody th{text-align:left;}#djDebug .djSqlExplain td{white-space:pre;}#djDebug span.djDebugLineChart{background-color:#777;height:3px;position:absolute;bottom:0;top:0;left:0;display:block;z-index:1000000001;}#djDebug span.djDebugLineChartWarning{background-color:#900;}#djDebug .highlight{color:#000;}#djDebug .highlight .err{color:#000;}#djDebug .highlight .g{color:#000;}#djDebug .highlight .k{color:#000;font-weight:bold;}#djDebug .highlight .o{color:#000;}#djDebug .highlight .n{color:#000;}#djDebug .highlight .mi{color:#000;font-weight:bold;}#djDebug .highlight .l{color:#000;}#djDebug .highlight .x{color:#000;}#djDebug .highlight .p{color:#000;}#djDebug .highlight .m{color:#000;font-weight:bold;}#djDebug .highlight .s{color:#333;}#djDebug .highlight .w{color:#888;}#djDebug .highlight .il{color:#000;font-weight:bold;}#djDebug .highlight .na{color:#333;}#djDebug .highlight .nt{color:#000;font-weight:bold;}#djDebug .highlight .nv{color:#333;}#djDebug .highlight .s2{color:#333;}#djDebug .highlight .cp{color:#333;}
View
4 debug_toolbar/media/debug_toolbar/js/toolbar.js
@@ -62,6 +62,10 @@
djdt.toggle_content($('.djSQLHideStacktraceDiv', $(this).parents('tr')));
return false;
});
+ $('#djDebugCachePanel a.djCacheShowStacktrace').click(function() {
+ djdt.toggle_content($('.djCacheHideStacktraceDiv', $(this).parents('tr')));
+ return false;
+ });
$('#djHideToolBarButton').click(function() {
djdt.hide_toolbar(true);
return false;
View
2 debug_toolbar/media/debug_toolbar/js/toolbar.min.js
@@ -1 +1 @@
-(function(g,a,b,i){var f,h;var e=false;if(!(f=g.jQuery)||b>f.fn.jquery||i(f)){var c=a.createElement("script");c.type="text/javascript";c.src=DEBUG_TOOLBAR_MEDIA_URL+"js/jquery.js";c.onload=c.onreadystatechange=function(){if(!e&&(!(h=this.readyState)||h=="loaded"||h=="complete")){i((f=g.jQuery).noConflict(1),e=true);f(c).remove()}};a.documentElement.childNodes[0].appendChild(c)}})(window,document,"1.3",function(b,a){b.cookie=function(f,n,q){if(typeof n!="undefined"){q=q||{};if(n===null){n="";q.expires=-1}var j="";if(q.expires&&(typeof q.expires=="number"||q.expires.toUTCString)){var k;if(typeof q.expires=="number"){k=new Date();k.setTime(k.getTime()+(q.expires*24*60*60*1000))}else{k=q.expires}j="; expires="+k.toUTCString()}var p=q.path?"; path="+(q.path):"";var l=q.domain?"; domain="+(q.domain):"";var e=q.secure?"; secure":"";document.cookie=[f,"=",encodeURIComponent(n),j,p,l,e].join("")}else{var h=null;if(document.cookie&&document.cookie!=""){var o=document.cookie.split(";");for(var m=0;m<o.length;m++){var g=b.trim(o[m]);if(g.substring(0,f.length+1)==(f+"=")){h=decodeURIComponent(g.substring(f.length+1));break}}}return h}};b("head").append('<link rel="stylesheet" href="'+DEBUG_TOOLBAR_MEDIA_URL+'css/toolbar.min.css" type="text/css" />');var d="djdt";var c={init:function(){b("#djDebug").show();var e=null;b("#djDebugPanelList li a").click(function(){if(!this.className){return false}e=b("#djDebug #"+this.className);if(e.is(":visible")){b(document).trigger("close.djDebug");b(this).parent().removeClass("active")}else{b(".panelContent").hide();e.show();b("#djDebugToolbar li").removeClass("active");b(this).parent().addClass("active")}return false});b("#djDebug a.djDebugClose").click(function(){b(document).trigger("close.djDebug");b("#djDebugToolbar li").removeClass("active");return false});b("#djDebug a.remoteCall").click(function(){b("#djDebugWindow").load(this.href,{},function(){b("#djDebugWindow a.djDebugBack").click(function(){b(this).parent().parent().hide();return false})});b("#djDebugWindow").show();return false});b("#djDebugTemplatePanel a.djTemplateShowContext").click(function(){c.toggle_arrow(b(this).children(".toggleArrow"));c.toggle_content(b(this).parent().next());return false});b("#djDebugSQLPanel a.djSQLShowStacktrace").click(function(){c.toggle_content(b(".djSQLHideStacktraceDiv",b(this).parents("tr")));return false});b("#djHideToolBarButton").click(function(){c.hide_toolbar(true);return false});b("#djShowToolBarButton").click(function(){c.show_toolbar();return false});b(document).bind("close.djDebug",function(){if(b("#djDebugWindow").is(":visible")){b("#djDebugWindow").hide();return}if(b(".panelContent").is(":visible")){b(".panelContent").hide();return}if(b("#djDebugToolbar").is(":visible")){c.hide_toolbar(true);return}});if(b.cookie(d)){c.hide_toolbar(false)}else{c.show_toolbar(false)}},toggle_content:function(e){if(e.is(":visible")){e.hide()}else{e.show()}},close:function(){b(document).trigger("close.djDebug");return false},hide_toolbar:function(e){b("#djDebugWindow").hide();b(".panelContent").hide();b("#djDebugToolbar li").removeClass("active");b("#djDebugToolbar").hide("fast");b("#djDebugToolbarHandle").show();b(document).unbind("keydown.djDebug");if(e){b.cookie(d,"hide",{path:"/",expires:10})}},show_toolbar:function(e){b(document).bind("keydown.djDebug",function(f){if(f.keyCode==27){c.close()}});b("#djDebugToolbarHandle").hide();if(e){b("#djDebugToolbar").show("fast")}else{b("#djDebugToolbar").show()}b.cookie(d,null,{path:"/",expires:-1})},toggle_arrow:function(f){var e=String.fromCharCode(9654);var g=String.fromCharCode(9660);f.html(f.html()==e?g:e)}};b(document).ready(function(){c.init()})});
+(function(g,a,b,i){var f,h;var e=false;if(!(f=g.jQuery)||b>f.fn.jquery||i(f)){var c=a.createElement("script");c.type="text/javascript";c.src=DEBUG_TOOLBAR_MEDIA_URL+"js/jquery.js";c.onload=c.onreadystatechange=function(){if(!e&&(!(h=this.readyState)||h=="loaded"||h=="complete")){i((f=g.jQuery).noConflict(1),e=true);f(c).remove()}};a.documentElement.childNodes[0].appendChild(c)}})(window,document,"1.3",function(b,a){b.cookie=function(f,n,q){if(typeof n!="undefined"){q=q||{};if(n===null){n="";q.expires=-1}var j="";if(q.expires&&(typeof q.expires=="number"||q.expires.toUTCString)){var k;if(typeof q.expires=="number"){k=new Date();k.setTime(k.getTime()+(q.expires*24*60*60*1000))}else{k=q.expires}j="; expires="+k.toUTCString()}var p=q.path?"; path="+(q.path):"";var l=q.domain?"; domain="+(q.domain):"";var e=q.secure?"; secure":"";document.cookie=[f,"=",encodeURIComponent(n),j,p,l,e].join("")}else{var h=null;if(document.cookie&&document.cookie!=""){var o=document.cookie.split(";");for(var m=0;m<o.length;m++){var g=b.trim(o[m]);if(g.substring(0,f.length+1)==(f+"=")){h=decodeURIComponent(g.substring(f.length+1));break}}}return h}};b("head").append('<link rel="stylesheet" href="'+DEBUG_TOOLBAR_MEDIA_URL+'css/toolbar.min.css" type="text/css" />');var d="djdt";var c={init:function(){b("#djDebug").show();var e=null;b("#djDebugPanelList li a").click(function(){if(!this.className){return false}e=b("#djDebug #"+this.className);if(e.is(":visible")){b(document).trigger("close.djDebug");b(this).parent().removeClass("active")}else{b(".panelContent").hide();e.show();b("#djDebugToolbar li").removeClass("active");b(this).parent().addClass("active")}return false});b("#djDebug a.djDebugClose").click(function(){b(document).trigger("close.djDebug");b("#djDebugToolbar li").removeClass("active");return false});b("#djDebug a.remoteCall").click(function(){b("#djDebugWindow").load(this.href,{},function(){b("#djDebugWindow a.djDebugBack").click(function(){b(this).parent().parent().hide();return false})});b("#djDebugWindow").show();return false});b("#djDebugTemplatePanel a.djTemplateShowContext").click(function(){c.toggle_arrow(b(this).children(".toggleArrow"));c.toggle_content(b(this).parent().next());return false});b("#djDebugSQLPanel a.djSQLShowStacktrace").click(function(){c.toggle_content(b(".djSQLHideStacktraceDiv",b(this).parents("tr")));return false});b("#djDebugCachePanel a.djCacheShowStacktrace").click(function(){c.toggle_content(b(".djCacheHideStacktraceDiv",b(this).parents("tr")));return false});b("#djHideToolBarButton").click(function(){c.hide_toolbar(true);return false});b("#djShowToolBarButton").click(function(){c.show_toolbar();return false});b(document).bind("close.djDebug",function(){if(b("#djDebugWindow").is(":visible")){b("#djDebugWindow").hide();return}if(b(".panelContent").is(":visible")){b(".panelContent").hide();return}if(b("#djDebugToolbar").is(":visible")){c.hide_toolbar(true);return}});if(b.cookie(d)){c.hide_toolbar(false)}else{c.show_toolbar(false)}},toggle_content:function(e){if(e.is(":visible")){e.hide()}else{e.show()}},close:function(){b(document).trigger("close.djDebug");return false},hide_toolbar:function(e){b("#djDebugWindow").hide();b(".panelContent").hide();b("#djDebugToolbar li").removeClass("active");b("#djDebugToolbar").hide("fast");b("#djDebugToolbarHandle").show();b(document).unbind("keydown.djDebug");if(e){b.cookie(d,"hide",{path:"/",expires:10})}},show_toolbar:function(e){b(document).bind("keydown.djDebug",function(f){if(f.keyCode==27){c.close()}});b("#djDebugToolbarHandle").hide();if(e){b("#djDebugToolbar").show("fast")}else{b("#djDebugToolbar").show()}b.cookie(d,null,{path:"/",expires:-1})},toggle_arrow:function(f){var e=String.fromCharCode(9654);var g=String.fromCharCode(9660);f.html(f.html()==e?g:e)}};b(document).ready(function(){c.init()})});
View
200 debug_toolbar/panels/cache.py
@@ -1,73 +1,102 @@
import time
-import inspect
+import sys
+import traceback
-from django.core import cache
+import django.dispatch
+from django.core.cache import get_cache
from django.core.cache.backends.base import BaseCache
from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _
from debug_toolbar.panels import DebugPanel
+from debug_toolbar.panels.sql import tidy_stacktrace
+
+cache_call = django.dispatch.Signal(providing_args=["time_taken", "name", "return_value", "args", "trace"])
+
+def debug_cache_backend(dummy, params):
+ backend = 'BACKEND_TO_MONITOR' in params and params['BACKEND_TO_MONITOR'] or 'default'
+ cache = get_cache(backend)
+ return CacheStatTracker(cache)
class CacheStatTracker(BaseCache):
"""A small class used to track cache calls."""
def __init__(self, cache):
self.cache = cache
- self.reset()
-
- def reset(self):
- self.calls = []
- self.hits = 0
- self.misses = 0
- self.sets = 0
- self.gets = 0
- self.get_many = 0
- self.deletes = 0
- self.total_time = 0
-
+
+ def _send_call_signal(method):
+ def wrapped(self, *args, **kwargs):
+ t = time.time()
+ value = method(self, *args, **kwargs)
+ t = time.time() - t
+
+ # FIXME: factorize this, it's copy/pasted from sql.py
+ stacktrace = tidy_stacktrace(traceback.extract_stack())
+ template_info = None
+ cur_frame = sys._getframe().f_back
+ try:
+ while cur_frame is not None:
+ if cur_frame.f_code.co_name == 'render':
+ node = cur_frame.f_locals['self']
+ if isinstance(node, Node):
+ template_info = get_template_info(node.source)
+ break
+ cur_frame = cur_frame.f_back
+ except:
+ pass
+ del cur_frame
+
+ cache_call.send(sender=self, time_taken=t, name=method.__name__,
+ return_value=value, args=args[0],
+ trace=stacktrace, template_info=template_info)
+ return value
+ return wrapped
+
def _get_func_info(self):
stack = inspect.stack()[2]
- return (stack[1], stack[2], stack[3], stack[4])
-
- def get(self, key, default=None):
- t = time.time()
- value = self.cache.get(key, default)
- this_time = time.time() - t
- self.total_time += this_time * 1000
- if value is None:
- self.misses += 1
- else:
- self.hits += 1
- self.gets += 1
- self.calls.append((this_time, 'get', (key,), self._get_func_info()))
- return value
-
- def set(self, key, value, timeout=None):
- t = time.time()
- self.cache.set(key, value, timeout)
- this_time = time.time() - t
- self.total_time += this_time * 1000
- self.sets += 1
- self.calls.append((this_time, 'set', (key, value, timeout), self._get_func_info()))
-
- def delete(self, key):
- t = time.time()
- self.cache.delete(key)
- this_time = time.time() - t
- self.total_time += this_time * 1000
- self.deletes += 1
- self.calls.append((this_time, 'delete', (key,), self._get_func_info()))
-
- def get_many(self, keys):
- t = time.time()
- results = self.cache.get_many(keys)
- this_time = time.time() - t
- self.total_time += this_time * 1000
- self.get_many += 1
- for key, value in results.iteritems():
- if value is None:
- self.misses += 1
- else:
- self.hits += 1
- self.calls.append((this_time, 'get_many', (keys,), self._get_func_info()))
+ return (stack[1], stack[2], stack[3], stack[4])
+
+ @_send_call_signal
+ def add(self, key, value, timeout=None, version=None):
+ return self.cache.add(key, value, timeout, version)
+
+ @_send_call_signal
+ def get(self, key, default=None, version=None):
+ return self.cache.get(key, default, version)
+
+ @_send_call_signal
+ def set(self, key, value, timeout=None, version=None):
+ return self.cache.set(key, value, timeout, version)
+
+ @_send_call_signal
+ def delete(self, key, version=None):
+ return self.cache.get(key, version)
+
+ @_send_call_signal
+ def get_many(self, keys, version=None):
+ return self.cache.get_many(key, version)
+
+ @_send_call_signal
+ def has_key(self, key, version=None):
+ return self.cache.has_key(key, version)
+
+ @_send_call_signal
+ def incr(self, key, delta=1, version=None):
+ return self.cache.incr(key, delta, version)
+
+ @_send_call_signal
+ def decr(self, key, delta=1, version=None):
+ return self.cache.decr(key, delta, version)
+
+ @_send_call_signal
+ def set_many(self, data, timeout=None, version=None):
+ return self.cache.set_many(data, timeout, version)
+
+ @_send_call_signal
+ def delete_many(self, keys, version=None):
+ return self.cache.delete_many(keys, version)
+
+ @_send_call_signal
+ def clear(self):
+ return self.cache.clear()
class CacheDebugPanel(DebugPanel):
"""
@@ -78,16 +107,48 @@ class CacheDebugPanel(DebugPanel):
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
- # This is hackish but to prevent threading issues is somewhat needed
- if isinstance(cache.cache, CacheStatTracker):
- cache.cache.reset()
- self.cache = cache.cache
- else:
- self.cache = CacheStatTracker(cache.cache)
- cache.cache = self.cache
+ self.total_time = 0
+ self.hits = 0
+ self.misses = 0
+ self.calls = []
+ self.stats = {
+ 'add' : 0,
+ 'get' : 0,
+ 'set' : 0,
+ 'delete' : 0,
+ 'get_many' : 0,
+ 'set_many' : 0,
+ 'delete_many' : 0,
+ 'has_key' : 0,
+ 'incr' : 0,
+ 'decr' : 0
+ }
+ cache_call.connect(self._store_call_info)
+
+ def _store_call_info(self, sender, name=None, time_taken=0, return_value=None, args=None, trace=None, **kwargs):
+ if name == 'get':
+ if return_value is None:
+ self.misses += 1
+ else:
+ self.hits += 1
+ elif name == 'get_many':
+ for key, value in return_value.iteritems():
+ if value is None:
+ self.misses += 1
+ else:
+ self.hits += 1
+ self.total_time += time_taken * 1000
+ self.stats[name] += 1
+ self.calls.append({
+ 'time' : time_taken,
+ 'name' : name,
+ 'args' : unicode(args),
+ 'trace': trace,
+ 'template_info': kwargs.get('template_info', None)
+ })
def nav_title(self):
- return _('Cache: %.2fms') % self.cache.total_time
+ return _('Cache: %.2fms') % self.total_time
def title(self):
return _('Cache Usage')
@@ -98,8 +159,11 @@ def url(self):
def content(self):
context = self.context.copy()
context.update({
- 'cache_calls': len(self.cache.calls),
- 'cache_time': self.cache.total_time,
- 'cache': self.cache,
+ 'cache_total_calls': len(self.calls),
+ 'cache_calls' : self.calls,
+ 'cache_time': self.total_time,
+ 'cache_hits': self.hits,
+ 'cache_misses': self.misses,
+ 'cache_stats' : self.stats
})
return render_to_string('debug_toolbar/panels/cache.html', context)
View
81 debug_toolbar/templates/debug_toolbar/panels/cache.html
@@ -1,54 +1,71 @@
{% load i18n %}
+<h3>{% trans "Summary" %}</h3>
<table>
- <colgroup>
- <col width="12%"/>
- <col width="12%"/>
- <col width="12%"/>
- <col width="12%"/>
- <col width="12%"/>
- <col width="12%"/>
- <col width="12%"/>
- <col width="12%"/>
- </colgroup>
+ <thead>
<tr>
<th>{% trans "Total Calls" %}</th>
- <td>{{ cache_calls }}</td>
<th>{% trans "Total Time" %}</th>
- <td>{{ cache_time }}ms</td>
- <th>{% trans "Hits" %}</th>
- <td>{{ cache.hits }}</td>
- <th>{% trans "Misses" %}</th>
- <td>{{ cache.misses }}</td>
+ <th>{% trans "Cache Hits" %}</th>
+ <th>{% trans "Cache Misses" %}</th>
</tr>
+ </thead>
+ <tbody>
<tr>
- <th>gets</th>
- <td>{{ cache.gets }}</td>
- <th>sets</th>
- <td>{{ cache.sets }}</td>
- <th>deletes</th>
- <td>{{ cache.deletes }}</td>
- <th>get_many</th>
- <td>{{ cache.get_many }}</td>
+ <td> {{ cache_total_calls }} </td>
+ <td> {{ cache_time }} ms </td>
+ <td> {{ cache_hits }} </td>
+ <td> {{ cache_misses }}</td>
</tr>
+ </tbody>
+</table>
+<h3>{% trans "Stats by command" %}</h3>
+<table>
+ {% for key, value in cache_stats.iteritems %}
+ <tr class="{% cycle 'djDebugOdd' 'djDebugEven' %}">
+ <td> {{ key }} </td>
+ <td> {{ value }} </td>
+ </tr>
+ {% endfor %}
</table>
-{% if cache.calls %}
-<h3>{% trans "Breakdown" %}</h3>
+{% if cache_calls %}
+<h3>{% trans "Queries" %}</h3>
<table>
<thead>
<tr>
<th>{% trans "Time" %}&nbsp;(ms)</th>
<th>{% trans "Type" %}</th>
+ <th>{% trans 'Stacktrace' %}</th>
<th>{% trans "Parameters" %}</th>
- <th>{% trans "Function" %}</th>
</tr>
</thead>
<tbody>
- {% for query in cache.calls %}
+ {% for query in cache_calls %}
<tr class="{% cycle 'row1' 'row2' %}">
- <td>{{ query.0|floatformat:"4" }}</td>
- <td>{{ query.1|escape }}</td>
- <td>{{ query.2|escape }}</td>
- <td><acronym title="{{ query.3.0 }}:{{ query.3.1 }}">{{ query.3.2|escape }}</acronym>: {{ query.3.3.0|escape }}</td>
+ <td>{{ query.time|floatformat:"4" }}</td>
+ <td>{{ query.name|escape }}</td>
+ <td style="width: 10em;">
+ <div class="djCacheShowStacktraceDiv"><a class="djCacheShowStacktrace" href="#">Toggle Stacktrace</a></div>
+ </td>
+ <td>{{ query.args|escape }}
+ {% with query.trace as stacktrace %}
+ <div class="djCacheHideStacktraceDiv" style="display: none;">
+ <table>
+ <tr>
+ <th>{% trans "Line" %}</th>
+ <th>{% trans "Method" %}</th>
+ <th>{% trans "File" %}</th>
+ </tr>
+ {% for file, line, method in stacktrace %}
+ <tr>
+ <td>{{ line }}</td>
+ <td><code>{{ method|escape }}</code></td>
+ <td><code>{{ file|escape }}</code></td>
+ </tr>
+ {% endfor %}
+ </table>
+ </div>
+ {% endwith %}
+ </td>
</tr>
{% endfor %}
</tbody>

0 comments on commit 9aa062b

Please sign in to comment.