2012-10-01 29 views
-1

我覺得我失去了非常明顯的東西,但我看不到它。如何從Django的GET請求中反序列化JSON字符串?

在IPython中(Python 2.7版),這部作品:

In [1]: json.loads('[]') 
Out[1]: [] 

我試圖做一個Django視圖相當於最小的例子,來說服自己,我可以閱讀JSON在移動到一個真實的數據之前,結構:

def submit(request): 
    json_string = request.GET['json'] 
    parsed = json.loads(json_string) 

    return HttpResponse(parsed) 

我轉到

http://localhost:8001/submit/?json='[]' 

把它從我的瀏覽器,我得到ValueError: No JSON object could be decoded

我在做什麼錯,我該如何調試?這是一種編碼問題嗎?或者我正確訪問GET的內容?或者是其他東西?

我試着將變量json_string轉儲到文件和HttpResponse。這兩次我得到'[]',這肯定看起來精...

編輯:

對於其他任何初學者想知道如何調試POST的利益,Django的錯誤頁面是在異常返回。一個快速而骯髒的破解工作是

import os 
def debug_post(post_req): 

    result = None 
    try: 
     result = submit_to_endpoint(post_req) 
    except urllib2.URLError as e: 
     out_fh = open('debug_post.tmp', 'w') 
     out_fh.write(e.read()) 
     out_fh.close() 
     os.system('firefox ' + 'debug.tmp') 

    return result 
+0

'?json = []'? – 2012-10-01 11:43:38

+0

oO任何不使用POST的理由? –

+0

@BasicWolf - 不,這只是簡單的測試(我可以剪切和粘貼我的客戶端編碼的URL直接進入瀏覽器)。 POST是更好的選擇嗎?爲什麼? –

回答

3

您已經在JSON字符串中包含單引號。沒有必要,特別是單引號在JSON中無效。你應該去http://localhost:8001/submit/?json=[]

+0

好的,這個工程。所以在ipython的例子中,單引號表示一個Python字符串,但是在GET請求中,它們被作爲文字字符傳入,是嗎? –

+0

@ire_and_curses是的 - 沒錯。不過,你將會使用POST來處理真正的JSON數據,對嗎? –

+0

@Jon Clements - 我當然可以。是否有理由更喜歡它(你能告訴我是新來的)? –

2

雖然即使爲了測試目的,GET也許看起來更容易,但對於JSON,您應該使用POST請求。 這在請求改變應用程序內部狀態的情況下非常重要。例如。 /localhost/format/?json={disk_id : 1}是改變應用程序狀態的東西:)通常搜索引擎會索引網站的鏈接,這些鏈接是GET請求。想象一下像這樣的鏈接被搜索引擎索引:即使在索引過程中,應用程序的內部狀態也可以改變。

另一個原因是由網絡服務器,代理和瀏覽器實現的URLS緩存。猜猜看,GET請求的響應是通常被緩存的。

最後但並非最不重要的,GET請求參數預計將只需在Query string

localhost?key1=val1&key2=val2 

格式,其中val's是單值數據字段,而不是JSON數據。

所以,原因是在HTTP協議設計中。您可以利用例如AJAX技術來發布JSON數據,這足以避免上述所有情況。

我建議您熟悉RESTful網絡服務的想法 - 這是一個簡單而強大的設計用戶與Web應用程序通信的概念。

+0

謝謝,這很有幫助。當通過Firefox轉儲預先構建的網址時,它看起來也像[字符限制](http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url)。我已經切換到POST。 –

+0

對於未來的REST初學者,我還注意到我發現了一種調試POST輸出的簡單方法,它提供了與GET類似的功能。看我的編輯。 –