|
1 | 1 | import inspect
|
2 |
| -from collections import defaultdict |
| 2 | +from collections import Callable, defaultdict |
3 | 3 | from time import time
|
4 | 4 |
|
5 | 5 | import wrapt
|
6 | 6 | from debug_toolbar.panels import Panel
|
7 | 7 | from debug_toolbar.panels.sql.utils import contrasting_color_generator
|
8 | 8 | from django.dispatch import Signal
|
| 9 | +from django.urls import resolve |
9 | 10 | from django.utils.translation import ugettext_lazy as _
|
10 | 11 |
|
11 | 12 | template_rendered = Signal(providing_args=[
|
|
16 | 17 | node_element_colors = {}
|
17 | 18 |
|
18 | 19 |
|
| 20 | +@wrapt.decorator |
| 21 | +def profile_method(wrapped, instance, args, kwargs): |
| 22 | + start = time() |
| 23 | + |
| 24 | + result = wrapped(*args, **kwargs) |
| 25 | + end = time() |
| 26 | + |
| 27 | + instance_name = ( |
| 28 | + (wrapped.__self__.__class__.__name__ + ".") |
| 29 | + if hasattr(wrapped, '__self__') else "" |
| 30 | + ) + wrapped.__name__ |
| 31 | + template_rendered.send( |
| 32 | + sender=instance.__class__, |
| 33 | + instance=instance_name, |
| 34 | + start=start, |
| 35 | + end=end, |
| 36 | + processing_timeline=[], |
| 37 | + level=1, |
| 38 | + ) |
| 39 | + return result |
| 40 | + |
| 41 | + |
19 | 42 | def get_nodelist_timeline(nodelist, level):
|
20 | 43 | timeline = []
|
21 | 44 | for node in nodelist:
|
@@ -70,6 +93,22 @@ def __init__(self, *args, **kwargs):
|
70 | 93 |
|
71 | 94 | have_monkey_patched_template_classes = False
|
72 | 95 |
|
| 96 | + def generate_stats(self, request, response): |
| 97 | + match = resolve(request.path) |
| 98 | + func, args, kwargs = match |
| 99 | + view_class = getattr(func, 'view_class', None) |
| 100 | + if view_class and not hasattr(view_class, '_profile_enabled'): |
| 101 | + print(view_class) |
| 102 | + view_class._profile_enabled = True |
| 103 | + for attr in view_class.__dict__: |
| 104 | + print(attr) |
| 105 | + if isinstance(getattr(view_class, attr), Callable): |
| 106 | + setattr( |
| 107 | + view_class, |
| 108 | + attr, |
| 109 | + profile_method(getattr(view_class, attr)), |
| 110 | + ) |
| 111 | + |
73 | 112 | @classmethod
|
74 | 113 | def monkey_patch_template_classes(cls):
|
75 | 114 | if cls.have_monkey_patched_template_classes:
|
@@ -151,7 +190,10 @@ def record(self, instance, start, end, level,
|
151 | 190 | if not self.enabled:
|
152 | 191 | return
|
153 | 192 |
|
154 |
| - template_name = instance.name |
| 193 | + try: |
| 194 | + template_name = instance.name |
| 195 | + except AttributeError: |
| 196 | + template_name = instance |
155 | 197 | # Logic copied from django-debug-toolbar:
|
156 | 198 | # https://github.com/jazzband/django-debug-toolbar/blob/5d095f66fde8f10b45a93c0b35be0a85762b0458/debug_toolbar/panels/templates/panel.py#L77
|
157 | 199 | is_skipped_template = isinstance(template_name, str) and (
|
|
0 commit comments