Ответ 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, пожалуйста, напишите мне в разделе комментариев.