Django работает слишком медленно при обработке исключений

В представлении, в котором происходит исключение, обрабатывается большой словарь, содержащий около ~350K записей. Исключение представляет собой KeyError.

Из журналов CProfile видно, что Django пытается итерировать словарь, чтобы получить данные о возвратах к трассировке.

Вот упрощенный код из представления:

@login_required
def export_plan_data(request):
    try:
        form = PortfolioPlanningForm(request.GET, user=request.user)
        file = get_export_file(user=request.user, form.get_params()) # This is where the exception happens

        filename = f"Plan {timezone.now().strftime('%Y-%m-%d %H:%M:%S')}.xlsx"
        response = HttpResponse(file, content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
        response["Content-Disposition"] = f"attachment; filename={filename}"
        return response
    except Exception as e:
        return JsonResponse({"error": "An error occurred while exporting the data"}, status=500)

Если я заключаю все представление в блок try/except и возвращаю свой пользовательский ответ при возникновении исключения, он возвращается примерно за 10 секунд, но если я удаляю блок try/except и позволяю Django обработать исключение, это занимает около 5 минут.

Вот дамп Cprofile:

Это вполне логично, особенно если DEBUG имеет значение True. В этом случае Django генерирует страницу, которая покажет обратную трассировку, а чтобы сделать ее более удобной, она даже добавляет содержание параметров всех вызовов функций.

Это означает, что если ваш трассировщик где-то передаст ваш словарь с этими 350k+ записями, то он теперь начнет печатать их, чтобы добавить их в ответ. Действительно, вы можете посмотреть на ответ об ошибке, расширить трассировку, а затем расширить переменные. Они не определяются, когда вы расширяете список переменных, но Django готовит полный ответ.

Вернуться на верх