I use this sometimes to get insight into how long some view functions take. Perhaps you find it useful too:


def view_function_timer(prefix='', writeto=print):

    def decorator(func):
        @functools.wraps(func)
        def inner(*args, **kwargs):
            try:
                t0 = time.time()
                return func(*args, **kwargs)
            finally:
                t1 = time.time()
                writeto(
                    'View Function',
                    '({})'.format(prefix) if prefix else '',
                    func.__name__,
                    args[1:],
                    'Took',
                    '{:.2f}ms'.format(1000 * (t1 - t0)),
                    args[0].build_absolute_uri(),
                )
        return inner

    return decorator

And to use it:


from wherever import view_function_timer


@view_function_timer()
def homepage(request, thing):
    ...
    return render(request, template, context)

And then it prints something like this:

View Function  homepage ('valueofthing',) Took 23.22ms http://localhost:8000/home/valueofthing

It's useful when you don't want a full-blown solution to measure all view functions with a middleware or something.
It can be useful also to see how a cache decorator might work:


from django.views.decorators.cache import cache_page
from wherever import view_function_timer


@view_function_timer('possibly cached')
@cache_page(60 * 60 * 2)  # two hours cache
@view_function_timer('not cached')
def homepage(request, thing):
    ...
    return render(request, template, context)

That way you can trace that, with tail -f or something, to see how/if the cacheing decorator works.

There are many better solutions that are more robust but might be a bigger investment. For example, I would recommend markus which, if you don't have a statsd server you can configure to logger.info call the timings.

Comments

Chris Adams

It might be neat to add a Server-Timing header (https://www.w3.org/TR/server-timing/) on the response so the values could show up in the Chrome Developer Tools — e.g. see the network tab for http://httpbin.org/response-headers?Server-Timing=dur=5;%20database.

Peter Bengtsson

Neat! I'm not sure what the need/use for rust might be but yeah, a decorator like this would work. Or a middleware.

Your email will never ever be published.

Previous:
Synonyms with elasticsearch-dsl December 5, 2017 Python, Web development, PostgreSQL
Next:
How's My WiFi? December 8, 2017 Node, JavaScript, macOS
Related by category:
A Python dict that can report which keys you did not use June 12, 2025 Python
In Python, you have to specify the type and not rely on inference October 10, 2025 Python
Native connection pooling in Django 5 with PostgreSQL June 25, 2025 Django, Python
Combining Django signals with in-memory LRU cache August 9, 2025 Django, Python
Related by keyword:
Newfound love of @staticmethod in Python July 2, 2012 Python
Welcome to the world django-fancy-cache! March 1, 2013 Python, Django
Custom CacheMiddleware that tells Javascript a page is cached in Django August 24, 2009 Django
Secs sell! How I cache my entire pages (server-side) May 10, 2012 Python, Django