Подтвердить что ты не робот

Django: отображать время, необходимое для загрузки страницы на каждой странице

В Django, как я могу вернуть время , чтобы загрузить страницу (а не дату) на странице каждая сайта, без иметь записать в каждый view.py код, похожий на следующий:

start = time.time()
#model operations
loadingpagetime = time.time() - start

Если использовать TEMPLATE_CONTEXT_PROCESSOR, это лучший вариант.
Как я могу получить время загрузки всей страницы, вместо того, чтобы просто получать время загрузки шаблона?

UPDATE:

Поскольку первоначальный вопрос не кажется достаточно ясным, вот подход к тому, что будет версия Python того, что я хочу сделать.

#!/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 to my Django Webpage!</p>'
print '<p>Welcome to my Django Webpage!</p>'
print '<p>Welcome to my Django Webpage!</p>'
print '</div>'

time.sleep(3)
loadingtime = time.time() - start

print '<div>It took ',loadingtime,' seconds to load the page</div>'
print '</body>'
print '</html>'
4b9b3361

Ответ 1

Вы можете создать пользовательский middleware, чтобы зарегистрировать его. Вот как я создаю промежуточное ПО для достижения этой цели на 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"> и использовать CSS для этого div, но вы хотите, но НЕ меняйте комментарий <!-- STATS: .... -->. Если вы хотите изменить его, убедитесь, что вы проверили его против шаблона регулярного выражения в созданном middlewares.py.

Voila, наслаждайтесь статистикой.

EDIT:

Для тех, кто использует CBV (Class Based Views) много, вы, возможно, столкнулись с ошибкой 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, пожалуйста, напишите мне в разделе комментариев.

Ответ 2

Geordi дает вам потрясающее разбиение всего, что происходит в цикле запросов. Это промежуточное программное обеспечение, которое генерирует полное дерево вызовов, чтобы показать вам, что именно происходит и сколько времени тратится на каждую функцию.

Он выглядит следующим образом:

enter image description here

Я очень рекомендую его :)

Кредит изображения: http://evzijst.bitbucket.org/pycon.in

Ответ 3

Я могу ошибаться, но первое, что я вспомнил, это document.ready и ajax... Я не думаю, что это лучшее решение, но это должно быть довольно просто реализовать не только в django, но и в другом месте. Когда вы обрабатываете запрос в представлении, вы запускаете таймер, и когда document.ready запускается, вы вызываете ajax-вызов, чтобы остановить таймер. Но я должен признать, что @Hieu Nguyen довольно блестящий)

Ответ 4

Если вы хотите показать информацию о загрузке страницы своим посетителям, то ответ от Hieu Nguyen станет отличным вариантом. Но позвольте мне также порекомендовать вам хорошие инструменты.

Итак, если вам нужны эти данные только для целей разработки, посмотрите django-debug-toolbar. Он добавит приятную панель инструментов с полезной статистикой для каждой страницы, включая время, затраченное на запросы БД, рендеринг шаблонов и т.д.

Наконец, если вам нужны профессиональные инструменты профилирования для Djagno, Новая реликвия может быть очень хорошим выбором.

Ответ 5

Я обновил middleware.py. В нескольких словах мы добавляем уникальный текст в базовый шаблон, а затем заменяем его в Middleware process_response. Этот метод выглядит немного сложнее, но у нас есть время генерации ближе к true, и у нас нет проблем с javascript. Javascript на клиенте не может использовать заголовки страниц на первой загруженной странице, только если создать объект XHR, а затем получить страницу.

fooobar.com/info/99405/...