我如何在Django中进行故障排除?

时间:2014-10-20 02:35:44

标签: python django

我来自PHP背景,我一直在努力学习Python,但是我在调​​试时遇到了很多麻烦,因为我还不确定如何解决这个问题在Django或Python中。

我以前能够在PHP中使用print_rvar_dump所有内容。我可以在控制器,服务层或甚至模型和数据中显示在我的网络浏览器中。

我不能在Django中这样做。根据我正在做的事情,尝试在我的视图中对某个对象执行print会将页面关闭或输出到我的控制台,这对我来说并不是很有帮助。这是一个例子:

class Page(View):
    def get(self, request, *args, **kwargs):
       response = Data.objects.all()

       # for whatever reason, I want to print something right now:
       print response

       # return JsonResponse({'success':response})

以上内容将完全取消我的页面并发出通知说明:

The view didn't return an HttpResponse object. It returned None instead.

在使用CBV时有一些情况,我注意到我可以将数据转移到某个地方,例如控制台。但它不会有任何可以帮助我的东西。例如,如果我试图从上面看一下response的内容,它就会像这样出现:

[object Object] [object Object] [object Object]

var_dump会让我真正看到它内部。

所以我猜测我这一切都错了。当人们在Python中进行调试时,人们只是转储数据吗?如果他们这样做,你如何执行此操作,并将其显示在Web浏览器或控制台中?如果没有,我如何处理Django中的基本故障排除?示例场景:

  1. 我想查看列表或词典的内容
  2. 我想看看ORM正在执行的原始SQL查询
  3. 我想查看是否正在执行一项功能,方法是将一些文本内部滑动到前端输出

3 个答案:

答案 0 :(得分:5)

基本问题是您已经习惯了PHP如何连接到整个请求/响应链,而这不是开发Web应用程序时Python的配置方式。

在PHP-world中,服务器保证响应,从而关闭请求/响应周期。浏览器直接请求PHP文件,因此您不知道后台实际发生了什么。

典型的PHP请求与任何其他静态资产的请求相同,例如普通index.html文件或logo.gif。浏览器请求,Web服务器接受请求,然后返回响应;唯一的区别是,如果请求具有.php的文件,那么它将经历一个中间步骤,其中PHP解释器评估文件,并将结果发送回客户端。

然而,在Python中,当一个请求被映射到Python后端进程(有时称为上游进程)时; Web服务器等待进程的响应(可以调整此超时)。如果在定义的超时内未收到响应,则Web服务器将发送超时错误页面(504 ERROR)。

Python进程有责任按照浏览器的预期发送正确的响应(包含所有标题等)。在PHP中,这对您(作为开发人员)是隐藏的,因为PHP引擎将为您添加这些额外信息。因此,如果您的Python代码没有发送这样的响应(如您的情况),django会通过打印友好的错误消息来帮助您。

在您的情况下 - 视图未返回响应;它只是打印一些东西。此print语句将转到应用程序的标准输出(或错误流)(如果您在shell上启动它,将打印在控制台上,或写入服务器的日志等),它将不会被发送回客户端(浏览器)。

为了调试django应用程序:

  1. 确保DEBUG = True
  2. 中设置了settings.py
  3. 使用python manage.py runserver
  4. 运行您的应用程序

    现在,当您执行任何打印语句时,它将显示在控制台上,如果您的应用程序代码中存在错误 - 只要您返回有效的响应 - 您将获得一个丰富的错误页面以及堆栈跟踪以帮助识别问题。

    在开发过程中,没有更多“调试语句和打印机上的内容”;这就是Python连接到网络世界的方式。

    对于您的其他问题:

    1. 我想查看列表或词典的内容

      只需打印即可。输出将在您的控制台上(与您编写python manage.py runserver

    2. 的位置相同
    3. 我想看看ORM正在执行的原始SQL查询

      如果您要在django shell中测试一下,可以在ORM调用结束时放置.query以查看正在发送的查询:

       >>> result = MyModel.objects.filter(foo='bar')
       >>> result.query
       (query printed here)
      

      要获得更丰富的调试体验,请安装django_debug_toolbar

    4. 我想查看是否正在执行一项功能,方法是将一些文本滑入到前端输出

      没有“输出到前端”。对于这些事情,您可以print()只需要{0}},甚至更好use the logging system

答案 1 :(得分:3)

首先,您收到错误的原因不是因为您正在打印,而是因为您注释了退货:

class Page(View):
    def get(self, request, *args, **kwargs):
       response = Data.objects.all()

       # for whatever reason, I want to print something right now:
       print response

       return JsonResponse({'success':response}) # <-- dont comment this out

其次,打印任意对象并不总能提供最佳信息量。如果某些内容定义了__str____unicode__方法,则会将其打印到控制台。否则,将打印对象名称及其内存ID。不是最有用的。打印对象不会进行“深度”打印。

您可以尝试打印本地和全局:

print(locals())
print(globals())

或者将对象序列化为JSON并打印出来:

print(json.dumps(response)) # some objects may not be serialisable to JSON though.

但是你可能也没有得到你想要的细节数量。另一种方法是在调试模式下运行您的Web服务器,并引发异常:

# settings.py
DEBUG = True

# views.py
def my_view(request):
    raise Exception('debug')

..并依靠django向您显示调试错误页面,其中包含堆栈跟踪,并允许您检查每个帧中可用的所有变量。

答案 2 :(得分:1)

首先,Django视图需要返回某种HttpResponse对象。来自文档 - 与由Django自动创建的HttpRequest对象相比,HttpResponse对象是您的责任。您编写的每个视图都负责实例化,填充和返回HttpResponse。

您可以使用许多类来返回该响应(render_to_response,HttpResponseRedirect,JsonResponse以及许多,更多 - https://docs.djangoproject.com/en/dev/ref/request-response/#httpresponse-subclasses)。如果你摆脱#,你的#return JsonResponse({'success':response})就行了。

您可以使用Python的dir函数代替var_dump。将显示类或类实例的所有属性。见 - Is there a function in Python to print all the current properties and values of an object?

  1. 您可以打印字典。有很多方法可以做到这一点。

    表示your_dictionary.items()中的键值:     print(key,“:”,value)

  2. 容易做到。 print Data.objects.all()。query。请参阅 - How to show the SQL Django is running

  3. 或者你可以在函数内部添加print语句(或者说明函数正在执行的装饰器)。
  4. 这些是Django和Python的基本部分。不要太粗鲁,但是你的时间可能会比花在自己的项目上更好地完成一些教程。一旦点击,它将非常简单。 MVC / MVT框架具有与PHP不同的结构,您需要习惯于在其中工作或者会感到沮丧。