2014-10-20 176 views
4

我來自PHP背景,我一直在嘗試學習Python,但是在調試時遇到了很多麻煩,因爲我還不確定如何在Django或Python中進行這方面的工作。如何在Django中排除故障?

我已經習慣了能夠在PHP中使用print_rvar_dump。我可以在控制器中做到這一點,在服務層,甚至模型和數據都會顯示在我的Web瀏覽器中。

我不能在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. 的內容我想看到的原始SQL查詢由ORM
  3. 我想看看是否正在被執行的功能被執行滑動一些文本在前端輸出

回答

4

基本的問題是,您習慣了PHP如何連接到整個請求/響應鏈,而這不是開發Web應用程序時配置Python的方式。

在PHP世界中,服務器保證響應,該響應關閉請求/響應週期。 PHP文件是由瀏覽器直接請求的,所以您不知道背景中實際發生了什麼。

一個典型的PHP請求,與對任何其他靜態資產的請求一樣,如普通的index.html文件或logo.gif。瀏覽器請求,Web服務器接受請求,然後返回響應;唯一的區別是如果請求的文件是.php,那麼它會經歷一箇中間步驟,PHP解釋器評估文件並將結果發送回客戶端。然而,在Python中,當發出一個映射到Python後端進程(有時稱爲上游進程)的請求時, Web服務器等待進程的響應(可以調整此超時)。如果在定義的超時內未收到響應,則Web服務器發送超時錯誤頁面(504錯誤)。

Python進程負責發送正確的響應(包含所有頭信息等),正如瀏覽器所期望的那樣。在PHP中,這對於您(作爲開發人員)來說是隱藏的,因爲PHP引擎會爲您添加這些額外的信息。所以當你的Python代碼沒有發送這樣的響應(如你的情況),django通過打印友好的錯誤消息來幫助你。

在你的情況 - 視圖沒有返回響應;它只是印刷一些東西。此打印語句將轉到應用程序的標準輸出(或錯誤流)(如果您在shell上啓動它,或寫入服務器的日誌等,將打印在控制檯上),它不會被髮送回客戶端(瀏覽器)。

爲了調試Django應用程序:

  1. 確保DEBUG = Truesettings.py
  2. 設置運行與python manage.py runserver

您的應用程序現在,當你做任何打印語句時,它會在控制檯上顯示,如果您的應用程序代碼中有錯誤 - 只要您返回有效的響應 - 您將獲得一個豐富的錯誤頁面以及堆棧跟蹤,以幫助識別問題。

當你正在開發的時候,沒有更多的「瀏覽器上的調試語句和打印內容」;這正是Python連接到網絡世界的方式。

對於您的其他問題:

  1. 我想看到一個列表或字典

    的內容只需打印出來。輸出將是你的控制檯(你寫python manage.py runserver同一個地方)上

  2. 我想看到原始的SQL查詢,由ORM

    如果你是出在django shell測試的東西正在執行,你可以只是把.query在你的ORM通話結束時看到正在發送的查詢:

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

    對於一個更豐富的調試經驗,安裝django_debug_toolbar

  3. 我想看看如果通過滑移一些文本內要在前端

    輸出沒有「輸出到前端」執行的功能。對於這樣的事情,你可以只需print()你需要什麼,或者甚至更好use the logging system

1

首先,Django視圖需要某種類型的HttpResponse對象才能被返回。從docs- 與HttpRequest對象(由Django自動創建)相反,HttpResponse對象是您的責任。您編寫的每個視圖都負責實例化,填充和返回HttpResponse。

有許多類可以用來返回響應(render_to_response,HttpResponseRedirect,JsonResponse和許多,更多 - https://docs.djangoproject.com/en/dev/ref/request-response/#httpresponse-subclasses)。你的線路#返回JsonResponse({'success':response})將做到這一點,如果你擺脫#。

而不是var_dump,你可以使用Python的dir函數。將顯示類或類實例的所有屬性。請參閱-Is there a function in Python to print all the current properties and values of an object?

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

    關鍵,價值your_dictionary.items(): 打印(鍵, 「:」,值)

  2. 容易做到的。打印Data.objects。全部()。查詢。請參閱 - How to show the SQL Django is running

  3. 或者您可以在函數(或聲明函數正在執行的裝飾器)中添加打印語句。

這些是Django和Python的基本部分。不要粗魯,但你花時間完成一些教程可能會比開始自己的項目更好。一旦點擊,它將非常簡單。 MVC/MVT框架的結構與PHP不同,您需要習慣於在其中工作,否則會感到沮喪。

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. 

但你可能不會得到你想要的細節量從那個要麼。另一種方法是運行在調試模式下你的網絡服務器,並拋出一個異常:

# settings.py 
DEBUG = True 

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

..並依靠Django的向您展示調試錯誤頁面,其中包括一個堆棧跟蹤,並允許你檢查所有的每幀中可用的變量。

+0

對於'調試'模式的+1 - 這正是這是爲了什麼。 – Ben 2014-10-20 08:02:00