2013-04-03 137 views
2

django的一个很棒的功能是在On 500错误上返回的调试页面。Django调试错误页面无法在AJAX调用上工作

但是,在AJAX调用中,我收到了在DEBUG = False时会出现的纯文本错误。执行非AJAX请求时不会发生此问题:如果发生Internet服务器错误,则返回“正常”请求,然后返回漂亮的调试页。

我昨天升级了从django 1.3升级到1.5。

我的settings.py有folllowing:

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请求的域名):从

if request.is_ajax(): 

编辑django.views.debug 65行

if request.is_ajax() and settings.MINIFY_505_ON_AJAX

然后在settings.py

+0

请包含您的某个AJAX请求的代码。 – 2013-04-03 19:55:12

回答

2

在“好调试页”取决于调试环境(从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增加了有关模板渲染错误的额外信息。

UPDATE

这是它应该工作,如果request.is_ajax()为true,那么文本扫描是在响应主体返回的路上,检查源:

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

此行为已在1.4中更改,提交:https://github.com/django/django/commit/0d9b6a5bc43c06716212bd3f847460ce985381aa

UPDATE 2

这有点不好意思,但出于调试目的,您可以修改HTTP_X_REQUESTED_WITH标头,以便request.is_ajax()为false,然后强制执行html响应。 (请参阅https://github.com/django/django/blob/master/django/http/request.py#L136-137

+0

我的settings.py包含以下内容: DEBUG = True 此外,问题只发生在AJAX请求上。 – rikAtee 2013-04-03 20:42:32

+0

@rikAtee:这不是问题,这是它的意思,检查我的更新与源的链接。 – gonz 2013-04-03 21:06:03

+0

你真棒!谢谢。我做了以下内容: 编辑'technical_500_response'为'如果request.is_ajax()和settings.MINIFY_505_ON_AJAX:'和设置添加MINIFY_505_ON_AJAX =假 这是一个更容易维护修复,什么是Django的意思是,如果不维护! – rikAtee 2013-04-03 21:25:38

1

的添加选项仅适用于呈现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}) 

Exceptionrender_to_response之前提出的,所以TEMPLATE_DEBUG将永远不会有机会运行。

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

+0

嗯 - 奇怪。在Django 1.3中,我正在获得完整的调试页面。 – rikAtee 2013-04-03 20:09:47

+0

从1.3开始,功能似乎已经改变。以下是该文档版本的说明:“一个打开/关闭模板调试模式的布尔值,如果这是True,那么花哨的错误页面将显示任何TemplateSyntaxError的详细报告,该报告包含模板的相关片段,并突出显示适当的行。“ – 2013-04-03 20:13:59

+0

我使用提供的示例代码,仍然可以看到调试页面: http://i.imgur.com/QCOBCdr.png – rikAtee 2013-04-03 20:15:40