diff --git a/.gitignore b/.gitignore index 4f99c4f..5cd79b3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ *.pyc .tox *.egg-info -*.egg \ No newline at end of file +*.egg +.idea/ + +venv_debug/ diff --git a/debug_toolbar_mongo/operation_tracker.py b/debug_toolbar_mongo/operation_tracker.py index 607dfa6..11b6045 100644 --- a/debug_toolbar_mongo/operation_tracker.py +++ b/debug_toolbar_mongo/operation_tracker.py @@ -2,7 +2,7 @@ import time import inspect import os -import SocketServer +import socketserver import django from django.conf import settings @@ -14,7 +14,6 @@ __all__ = ['queries', 'inserts', 'updates', 'removes', 'install_tracker', 'uninstall_tracker', 'reset'] - _original_methods = { 'insert': pymongo.collection.Collection.insert, 'update': pymongo.collection.Collection.update, @@ -28,6 +27,8 @@ removes = [] WANT_STACK_TRACE = getattr(settings, 'DEBUG_TOOLBAR_MONGO_STACKTRACES', True) + + def _get_stacktrace(): if WANT_STACK_TRACE: try: @@ -51,7 +52,7 @@ def _get_stacktrace(): # Wrap Cursor._refresh for getting queries @functools.wraps(_original_methods['insert']) def _insert(collection_self, doc_or_docs, manipulate=True, - safe=False, check_keys=True, **kwargs): + safe=False, check_keys=True, **kwargs): start_time = time.time() result = _original_methods['insert']( collection_self, @@ -72,10 +73,11 @@ def _insert(collection_self, doc_or_docs, manipulate=True, }) return result + # Wrap Cursor._refresh for getting queries @functools.wraps(_original_methods['update']) def _update(collection_self, spec, document, upsert=False, - maniuplate=False, safe=False, multi=False, **kwargs): + maniuplate=False, safe=False, multi=False, **kwargs): start_time = time.time() result = _original_methods['update']( collection_self, @@ -100,6 +102,7 @@ def _update(collection_self, spec, document, upsert=False, }) return result + # Wrap Cursor._refresh for getting queries @functools.wraps(_original_methods['remove']) def _remove(collection_self, spec_or_id, safe=False, **kwargs): @@ -121,6 +124,7 @@ def _remove(collection_self, spec_or_id, safe=False, **kwargs): }) return result + # Wrap Cursor._refresh for getting queries @functools.wraps(_original_methods['refresh']) def _cursor_refresh(cursor_self): @@ -188,6 +192,7 @@ def privar(name): return result + def install_tracker(): if pymongo.collection.Collection.insert != _insert: pymongo.collection.Collection.insert = _insert @@ -198,6 +203,7 @@ def install_tracker(): if pymongo.cursor.Cursor._refresh != _cursor_refresh: pymongo.cursor.Cursor._refresh = _cursor_refresh + def uninstall_tracker(): if pymongo.collection.Collection.insert == _insert: pymongo.collection.Collection.insert = _original_methods['insert'] @@ -208,6 +214,7 @@ def uninstall_tracker(): if pymongo.cursor.Cursor._refresh == _cursor_refresh: pymongo.cursor.Cursor._refresh = _original_methods['cursor_refresh'] + def reset(): global queries, inserts, updates, removes queries = [] @@ -215,28 +222,31 @@ def reset(): updates = [] removes = [] + def _get_ordering(son): """Helper function to extract formatted ordering from dict. """ + def fmt(field, direction): return '{0}{1}'.format({-1: '-', 1: '+'}[direction], field) if '$orderby' in son: return ', '.join(fmt(f, d) for f, d in son['$orderby'].items()) + # Taken from Django Debug Toolbar 0.8.6 def _tidy_stacktrace(stack): """ Clean up stacktrace and remove all entries that: 1. Are part of Django (except contrib apps) - 2. Are part of SocketServer (used by Django's dev server) + 2. Are part of socketserver (used by Django's dev server) 3. Are the last entry (which is part of our stacktracing code) ``stack`` should be a list of frame tuples from ``inspect.stack()`` """ django_path = os.path.realpath(os.path.dirname(django.__file__)) django_path = os.path.normpath(os.path.join(django_path, '..')) - socketserver_path = os.path.realpath(os.path.dirname(SocketServer.__file__)) + socketserver_path = os.path.realpath(os.path.dirname(socketserver.__file__)) pymongo_path = os.path.realpath(os.path.dirname(pymongo.__file__)) trace = [] @@ -247,7 +257,7 @@ def _tidy_stacktrace(stack): if '__traceback_hide__' in frame.f_locals: continue if getattr(settings, 'DEBUG_TOOLBAR_CONFIG', {}).get('HIDE_DJANGO_SQL', True) \ - and django_path in s_path and not 'django/contrib' in s_path: + and django_path in s_path and not 'django/contrib' in s_path: continue if socketserver_path in s_path: continue @@ -259,4 +269,3 @@ def _tidy_stacktrace(stack): text = (''.join(text)).strip() trace.append((path, line_no, func_name, text)) return trace - diff --git a/debug_toolbar_mongo/panel.py b/debug_toolbar_mongo/panel.py index 5522621..332a9e8 100644 --- a/debug_toolbar_mongo/panel.py +++ b/debug_toolbar_mongo/panel.py @@ -1,10 +1,9 @@ from django.template import Template, Context -from django.template.loader import render_to_string from django.utils.safestring import mark_safe -from debug_toolbar.panels import DebugPanel +from debug_toolbar.panels import Panel -import operation_tracker +from . import operation_tracker _NAV_SUBTITLE_TPL = u''' {% for o, n, t in operations %} @@ -16,7 +15,8 @@ {% endfor %} ''' -class MongoDebugPanel(DebugPanel): + +class MongoDebugPanel(Panel): """Panel that shows information about MongoDB operations. """ name = 'MongoDB' @@ -24,7 +24,7 @@ class MongoDebugPanel(DebugPanel): template = 'mongo-panel.html' def __init__(self, *args, **kwargs): - super(MongoDebugPanel, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) operation_tracker.install_tracker() def process_request(self, request): diff --git a/example/manage.py b/example/manage.py index 7629979..35f7fd1 100755 --- a/example/manage.py +++ b/example/manage.py @@ -4,7 +4,10 @@ import settings # Assumed to be in the same directory. except ImportError: import sys - sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) + sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. " + "It appears you've customized things.\nYou'll have to run django-admin.py, " + "passing it your settings module.\n(If the file settings.py does indeed " + "exist, it's causing an ImportError somehow.)\n" % __file__) sys.exit(1) import sys diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..c528dc5 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +django>=2.1 + +django-debug-toolbar==1.11 + +pymongo