in django, how can return time it took load page (not date) in every page of site, without having write in every views.py code similar following one?
start = time.time() #model operations loadingpagetime = time.time() - start if using template_context_processor best option.
how whole page loading time there, instead of getting template loading time?
update:
as initial question doesn't seem clear enough, here approach of python version of want do.
#!/usr/bin/env python import cgitb; cgitb.enable() import time print 'content-type: text/html\n\n' start = time.time() print '<html>' print '<head>' print '</head>' print '<body>' print '<div>header</div>' print '<div>' print '<p>welcome django webpage!</p>' print '<p>welcome django webpage!</p>' print '<p>welcome django webpage!</p>' print '</div>' time.sleep(3) loadingtime = time.time() - start print '<div>it took ',loadingtime,' seconds load page</div>' print '</body>' print '</html>'
you can create custom middleware log this. here how create middleware achieve purpose base on http://djangosnippets.org/snippets/358/ (i modified code bit).
firstly, assuming project has name: test_project, create file name middlewares.py, place in same folder settings.py:
from django.db import connection time import time operator import add import re class statsmiddleware(object): def process_view(self, request, view_func, view_args, view_kwargs): ''' in base template, put this: <div id="stats"> <!-- stats: total: %(total_time).2fs python: %(python_time).2fs db: %(db_time).2fs queries: %(db_queries)d endstats --> </div> ''' # uncomment following if want stats on debug=true #if not settings.debug: # return none # number of db queries before n = len(connection.queries) # time view start = time() response = view_func(request, *view_args, **view_kwargs) total_time = time() - start # compute db time queries run db_queries = len(connection.queries) - n if db_queries: db_time = reduce(add, [float(q['time']) q in connection.queries[n:]]) else: db_time = 0.0 # , backout python time python_time = total_time - db_time stats = { 'total_time': total_time, 'python_time': python_time, 'db_time': db_time, 'db_queries': db_queries, } # replace comment if found if response , response.content: s = response.content regexp = re.compile(r'(?p<cmt><!--\s*stats:(?p<fmt>.*?)endstats\s*-->)') match = regexp.search(s) if match: s = (s[:match.start('cmt')] + match.group('fmt') % stats + s[match.end('cmt'):]) response.content = s return response secondly, modify settings.py add middleware:
middleware_classes = ( 'django.middleware.common.commonmiddleware', 'django.middleware.csrf.csrfviewmiddleware', # ... existing middlewares ... # custom middleware here 'test_project.middlewares.statsmiddleware', ) note: have add full path middleware class above, format is:
<project_name>.<middleware_file_name>.<middleware_class_name> a second note added middleware end of list because want log template load time alone. if want log load time of templates + middlewares, please put in beginning of middleware_classes list (credits @symmitchry).
back main topic, next step modify base.html or whatever pages want log load time, add this:
<div id="stats"> <!-- stats: total: %(total_time).2fs python: %(python_time).2fs db: %(db_time).2fs queries: %(db_queries)d endstats --> </div> note: can name <div id="stats"> , use css div want, don't change comment <!-- stats: .... -->. if want change it, sure test against regex pattern in created middlewares.py.
voila, enjoy statistics.
edit:
for use cbvs (class based views) lot, might have encountered error contentnotrenderederror above solution. have no fear, here fix in middlewares.py:
# replace comment if found if response: try: # detects templateresponse not yet rendered if response.is_rendered: rendered_content = response.content else: rendered_content = response.rendered_content except attributeerror: # django < 1.5 rendered_content = response.content if rendered_content: s = rendered_content regexp = re.compile( r'(?p<cmt><!--\s*stats:(?p<fmt>.*?)endstats\s*-->)' ) match = regexp.search(s) if match: s = (s[:match.start('cmt')] + match.group('fmt') % stats + s[match.end('cmt'):]) response.content = s return response i got working django 1.6.x, if have problem other version of django, please ping me in comment section.
Comments
Post a Comment