如何在 Django 中进行故障排除?
Posted
技术标签:
【中文标题】如何在 Django 中进行故障排除?【英文标题】:How do I troubleshoot in Django? 【发布时间】:2014-12-14 23:19:27 【问题描述】:我来自 php 背景,我一直在尝试学习 Python,但在调试时遇到了很多麻烦,因为我还不确定如何在 Django 或 Python 中进行此操作.
我习惯于在 PHP 中使用 print_r
或 var_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 中的基本故障排除?示例场景:
-
我想查看列表或字典的内容
我想查看 ORM 执行的原始 sql 查询
我想通过在前端输出一些文本来查看函数是否正在执行
【问题讨论】:
【参考方案1】:基本问题是你习惯了 PHP 是如何连接到整个请求/响应链中的,而这不是 Python 在开发 Web 应用程序时的配置方式。
在 PHP 世界中,服务器保证响应,从而关闭请求/响应周期。 PHP 文件是浏览器直接请求的,所以你不知道后台实际发生了什么。
典型的 PHP 请求与对任何其他静态资产的请求相同,例如普通的 index.html
文件或 logo.gif
。浏览器请求,Web服务器接受请求,然后返回响应;唯一的区别是,如果请求带有.php
的文件,那么它会经过一个中间步骤,PHP 解释器评估该文件,并将结果发送回客户端。
然而,在 Python 中,当发出映射到 Python 后端进程(有时称为上游进程)的请求时;网络服务器等待进程的响应(可以调整超时)。如果在定义的超时时间内没有收到响应,网络服务器会发送一个超时错误页面 (504 ERROR)。
Python 进程有责任按照浏览器的预期发送正确的响应(包括所有标头等)。在 PHP 中,这对您(作为开发人员)是隐藏的,因为 PHP 引擎会为您添加这些额外信息。因此,当您的 Python 代码不发送此类响应时(如您的情况),django 会通过打印友好的错误消息来帮助您。
在您的情况下 - 视图没有返回响应;它只是打印一些东西。此打印语句将转到应用程序的标准输出(或错误流)(如果您在 shell 上启动它,将在控制台上打印,或者写入服务器的日志等)它不会被发送回客户端(浏览器)。
为了调试 django 应用程序:
-
确保在您的
settings.py
中设置了DEBUG = True
使用python manage.py runserver
运行您的应用程序
现在,当您执行任何打印语句时,它将显示在控制台上,并且如果您的应用程序代码中有错误 - 只要您返回有效响应 - 您将获得一个丰富的错误页面以及堆栈跟踪以帮助识别问题。
在开发过程中不再有“在浏览器上调试语句和打印东西”;这就是 Python 连接到网络世界的方式。
关于您的其他问题:
我想查看列表或字典的内容
只需打印即可。输出将在您的控制台上(与您编写 python manage.py runserver
的地方相同)
我想查看 ORM 执行的原始 sql 查询
如果您在 django shell 中进行测试,您只需将 .query
放在 ORM 调用的末尾即可查看正在发送的查询:
>>> result = MyModel.objects.filter(foo='bar')
>>> result.query
(query printed here)
如需更丰富的调试体验,请安装django_debug_toolbar
。
我想通过在前端输出一些文本来查看是否正在执行函数
没有“输出到前端”。对于这样的事情,你可以print()
你需要的,或者更好的use the logging system。
【讨论】:
【参考方案2】:首先,您收到错误的原因不是因为您正在打印,而是因为您注释掉了返回:
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.
但您也可能无法从中获得所需的详细信息。另一种方法是在调试模式下运行您的网络服务器,并引发异常:
# settings.py
DEBUG = True
# views.py
def my_view(request):
raise Exception('debug')
.. 并依靠 django 向您显示调试错误页面,其中包括堆栈跟踪,并允许您检查每个帧中可用的所有变量。
【讨论】:
+1 表示DEBUG
模式——这正是它的用途。【参考方案3】:
首先,Django 视图需要返回某种 HttpResponse 对象。从文档 - 与 Django 自动创建的 HttpRequest 对象相比,HttpResponse 对象是您的责任。您编写的每个视图都负责实例化、填充和返回 HttpResponse。
您可以使用许多类来返回该响应(render_to_response、HttpResponseRedirect、JsonResponse 等等——https://docs.djangoproject.com/en/dev/ref/request-response/#httpresponse-subclasses)。如果您去掉 #.
您可以使用 Python 的 dir 函数来代替 var_dump。将显示类或类实例的所有属性。见-Is there a function in Python to print all the current properties and values of an object?
您可以打印字典。有很多方法可以做到这一点。
对于 your_dictionary.items() 中的键、值: 打印(键,“:”,值)
很容易做到。打印 Data.objects.all().query 。见-How to show the SQL Django is running
或者您可以在函数内部添加打印语句(或声明函数正在执行的装饰器)。这些是 Django 和 Python 的基本部分。不要粗鲁,但你的时间可能会更好地花在完整的教程上,而不是着手自己的项目。一旦点击,它将非常简单。 MVC/MVT 框架的结构与 PHP 不同,您需要习惯在其中工作,否则会感到沮丧。
【讨论】:
以上是关于如何在 Django 中进行故障排除?的主要内容,如果未能解决你的问题,请参考以下文章