您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Django:在每个页面上显示加载页面所需的时间

Django:在每个页面上显示加载页面所需的时间

您可以创建一个自定义中间件来进行记录。这是我基于http://djangosnippets.org/snippets/358/创建中间件以实现此目的的方式(我对代码进行了一些修改)。

首先,假设您的项目有一个名称test_project,创建一个文件middlewares.py,然后将其放置在与以下文件夹相同的文件夹中settings.py

from django.db import connection
from time import time
from operator import add
import re


class StatsMiddleware(object):

    def process_view(self, request, view_func, view_args, view_kwargs):
        '''
        In your 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 the following if you want to get stats on DEBUG=True only
        #if not settings.DEBUG:
        #    return None

        # get number of db queries before we do anything
        n = len(connection.queries)

        # time the view
        start = time()
        response = view_func(request, *view_args, **view_kwargs)
        total_time = time() - start

        # compute the db time for the queries just run
        db_queries = len(connection.queries) - n
        if db_queries:
            db_time = reduce(add, [float(q['time'])
                                   for q in connection.queries[n:]])
        else:
            db_time = 0.0

        # and 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 the comment if found
        if response and 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

其次,修改settings.py添加您的中间件:

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    # ... your existing middlewares ...

    # your custom middleware here
    'test_project.middlewares.StatsMiddleware',
)

注意:您必须像上面一样向中间件类添加完整路径,格式为:

<project_name>.<middleware_file_name>.<middleware_class_name>

第二个注意事项是我将此中间件添加到列表的末尾,因为我只想单独记录模板加载时间。如果要记录模板+所有中间件的加载时间,请把它放在MIDDLEWARE_CLASSES列表的开头(贷方为@Symmitchry)。

返回主题,下一步是修改base.html或您想要记录加载时间的任何页面添加以下内容

<div id="stats">
<!-- STATS: Total: %(total_time).2fs Python: %(python_time).2fs DB: %(db_time).2fs Queries: %(db_queries)d ENDSTATS -->
</div>

注意:您可以根据<div id="stats">需要为命名,并为该div使用CSS,但不要更改comment <!-- STATS: .... -->。如果要更改它,请确保已针对created中的正则表达式模式进行了测试middlewares.py

瞧,享受统计数据。

对于经常使用CBV(基于类的视图)的用户,您可能会遇到ContentNotRenderedError上述解决方案的错误。不用担心,这是修复方法middlewares.py

    # replace the comment if found
    if response:
        try:
            # detects TemplateResponse which are 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

我将其与Django 1.6.x配合使用,如果您对其他版本的Django有问题,请在评论部分ping我。

Go 2022/1/1 18:46:14 有367人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶