python - Django: display time it took to load a page on every page -


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