Django调试错误页面无法处理AJAX调用

时间:2013-04-03 19:45:22

标签: python django

django的一个很棒的功能是在On 500错误上返回的调试页面。

然而,在AJAX调用中,我得到了DEBUG = False时期望得到的纯文本错误。执行非AJAX请求时不会发生此问题:如果发生Internet服务器错误,则在“正常”请求中返回错误的调试页面。

我昨天将升级版从django 1.3升级到1.5。

我的settings.py包含以下内容:

DEBUG = True
TEMPLATE_DEBUG = True
TEMPLATE_CONTEXT_PROCESSORS contain django.core.context_processors.debug

我已将settings.py重置为“出厂设置”,但问题仍然存在。

受影响的大多数简单代码的示例 - 即使是最简单的代码也会受到影响:

def webservice(request):
     raise KeyError
     return HttpResponse('it didnt work')

以下请求调用此方法:

$.post('/webservice/', {'a':1, 'b':2})

必须注意我正在使用jquery,这个小宝贝所以csrf_token被添加到请求中:

$(document).ajaxSend(function(event, xhr, settings) {
        function sameOrigin(url) {
            var host = document.location.host, // host + port
                protocol = document.location.protocol,
                sr_origin = '//' + host,
                origin = protocol + sr_origin;
            return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
                (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
                // or any other URL that isn't scheme relative or absolute i.e relative.
                !(/^(\/\/|http:|https:).*/.test(url));
        }
        function safeMethod(method) {
            return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
        }
        if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
            xhr.setRequestHeader("X-CSRFToken", '{{csrf_token}}');
        }
    });

海外解决方案

行为在1.4中更改为仅在请求为ajax时返回回溯。下面是如何选择性地恢复该功能(当您主要在ajax请求的域中工作时,这非常有用):

修改django.views.debug第65行
if request.is_ajax():

if request.is_ajax() and settings.MINIFY_505_ON_AJAX

然后在MINIFY_505_ON_AJAX = False

中添加settings.py

2 个答案:

答案 0 :(得分:2)

“漂亮的调试页面”取决于DEBUG设置(来自https://docs.djangoproject.com/en/dev/ref/settings/#debug

One of the main features of debug mode is the display of detailed error pages.
If your app raises an exception when DEBUG is True, Django will display a 
detailed traceback, including a lot of metadata about your environment, such
as all the currently defined Django settings (from settings.py).

TEMPLATE_DEBUG添加了与模板渲染错误相关的额外信息。

<强>更新

如果request.is_ajax()为true,则它应该工作的方式然后在响应正文中返回文本回溯,检查源:

https://github.com/django/django/blob/master/django/views/debug.py#L59-70

此行为在1.4,commit:https://github.com/django/django/commit/0d9b6a5bc43c06716212bd3f847460ce985381aa

中已更改

更新2

这有点像hackish但是出于调试目的,您可以修改HTTP_X_REQUESTED_WITH标头,因此request.is_ajax()为false,然后强制执行html响应。 (见https://github.com/django/django/blob/master/django/http/request.py#L136-137

答案 1 :(得分:1)

TEMPLATE_DEBUG选项仅适用于呈现Django模板时发生的错误。由于您的函数不呈现任何模板,因此该选项无效。

来自https://docs.djangoproject.com/en/dev/ref/settings/#template-debug

  

打开/关闭模板调试模式的布尔值。如果这是真的,那么   花哨的错误页面将显示任何异常的详细报告   在模板渲染期间引发。该报告包含相关内容   模板的片段,突出显示相应的行。

这也意味着即使你的函数确实渲染了一个模板,如果在渲染模板之前发生了错误,你仍然会得到纯文本输出。

请注意,在以下示例中:

def year_archive(request, year):
    a_list = Article.objects.filter(pub_date__year=year)
    raise Exception("something horrible happened")
    return render_to_response('news/year_archive.html', {'year': year, 'article_list': a_list})

Exception之前提升render_to_response,因此TEMPLATE_DEBUG将永远无法运行。

如果要查看非模板错误的回溯,则需要查看命令行输出或日志。