Django-debug-toolbar-line-profiler показывает только одну строку вывода, без содержимого

У меня есть малина Pi, сидящая в отдаленном месте. Он подключен к небольшой домашней цепи и температурному зонду. Я создал малину Пи, чтобы сделать несколько вещей:

  • Выполнять cron задания каждый час, чтобы считывать температуру и хранить его локально в базе данных sqlite.
  • Запустите веб-сервер Nginx
  • Запустите сервер приложений uwsgi
  • Подача простого приложения Django

В этом приложении Django у меня есть простой вид, который делает следующее:

  • Попадите в БД, чтобы получить последние 300 записей температуры
  • Поместите их в Pandas DataFrame
  • Используйте Matplotlib для создания хорошего графика SVG недавней истории температуры.
  • Заполните простой шаблон, который отображает SVG, а также небольшую таблицу HTML последних температурных показаний.

Отображение этого представления занимает ~ 30 секунд. Очень долгое время. Поэтому я хотел посмотреть, что так долго. Я предполагаю, что все это связано с созданием графики. Но, чтобы узнать, я хотел сделать некоторые профилирования.

Я установил django-debug-toolbar, а также django-debug-toolbar-line-profiler, используя pip.

Я настроил их в соответствии с документами, насколько я понял. В частности, я установил:

DEBUG = True
TEMPLATE_DEBUG = DEBUG
DEBUG_TOOLBAR_PATCH_SETTINGS = False

MIDDLEWARE_CLASSES = (
    'debug_toolbar.middleware.DebugToolbarMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    # Uncomment the next line for simple clickjacking protection:
    # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

DEBUG_TOOLBAR_PANELS = (
    'debug_toolbar.panels.versions.VersionsPanel',
    'debug_toolbar.panels.timer.TimerPanel',
    'debug_toolbar.panels.settings.SettingsPanel',
    'debug_toolbar.panels.headers.HeadersPanel',
    'debug_toolbar.panels.sql.SQLPanel',
    'debug_toolbar.panels.staticfiles.StaticFilesPanel',
    'debug_toolbar.panels.templates.TemplatesPanel',
    'debug_toolbar.panels.cache.CachePanel',
    'debug_toolbar.panels.signals.SignalsPanel',
    'debug_toolbar.panels.logging.LoggingPanel',
    'debug_toolbar.panels.redirects.RedirectsPanel',

    'debug_toolbar_line_profiler.panel.ProfilingPanel',
)

Кроме того, INTERNAL_IPS также устанавливается правильно.

Я создал свое представление, используя представления на основе классов. Это выглядит так:

from django.views.generic import TemplateView
from XXXX.models import TempReading, TempSeries
import numpy as np
import pandas as pd
import matplotlib
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
import seaborn as sbn
import StringIO

class TestView(TemplateView):
    template_name = 'XXXX/test.html'

    def get_context_data(self, **kwargs):
        upstairs = TempSeries.objects.get(name='Upstairs')
        upstairstemps = upstairs.tempreading_set.all().order_by('-timestamp')[:300]

        frame = pd.DataFrame(list(upstairstemps.values()))
        frame.set_index('timestamp', inplace=True)

        # matplotlib.rcParams['svg.fonttype'] = 'none'

        fig = Figure()
        ax = fig.add_subplot(1,1,1)
        frame['value'].plot(ax=ax)
        ax.get_xaxis().grid(color='w', linewidth=1)
        ax.get_yaxis().grid(color='w', linewidth=1)

        fig.set(facecolor='w')
        canvas = FigureCanvas(fig)

        imgdata = StringIO.StringIO()
        canvas.print_svg(imgdata)

        imgstr = imgdata.getvalue()

        context = super(TestView, self).get_context_data(**kwargs)
        context['svgtext'] = imgstr
        context['htmltable'] = frame[:5].to_html()

        return context

Наиболее интересным для профилирования является get_context_data.

Когда я загружаю страницу, панель инструментов debug на самом деле появляется. Отображается панель профилирования. Но все, что я вижу, это:

{method 'disable' of '_lsprof.Profiler' objects}

Вот скриншот страницы с первой загрузкой: enter image description here

И вот как это выглядит на странице профилирования: enter image description here

Кажется, что он вообще не выполняет "профилирование линии"! Я ожидал увидеть временные результаты для каждой строки в моем классе. В частности, для каждой строки в функции get_context_data. Что происходит? Любая помощь очень ценится.


Изменить на 4/2

Как тест, я написал фиктивное представление, которое не использует представления на основе классов. И это, кажется, работает отлично. Здесь новый класс, не основанный на классе:

def testview2(request):
    df = pd.DataFrame({'a': np.random.randn(10), 'b': np.random.randn(10)})
    htmltable = df.to_html()
    context = {}
    context['htmltable'] = htmltable

    return render(request, 'XXXX/test2.html', context)

И это приводит к следующему результату в области профилирования: enter image description here

Итак, это работает нормально. Есть ли какая-то тонкость, которую мне не хватает в том, как debug-toolbar-line-profiler работает с представлениями на основе классов? В документах предполагается, что он будет обрабатывать любой метод класса, который не начинается с подчеркивания. Это неверно?

Ответ 1

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

Да, доверие JS может делать столько же, сколько питон. и он не будет на вашем сервере. Все эти графики, даже рендеринг шаблонов, вы должны перенести на клиентскую сторону. это, безусловно, исключит время обслуживания страницы для устройства типа чипа.

Что касается отладки, почему бы вам не отладить ее на реальном ПК, а затем переместить в Ras-Pi. вы можете добавить некоторую простую логику регистрации для проверки разделов, которые вы хотите изучить.

Ответ 2

Я заметил это, когда я украсил мои взгляды @csrf_exempt; после удаления профайлер работал нормально.

Не уверен, почему это вызывает проблему, но это исправило ее для меня.