2010-09-29 64 views
2

我試圖通過ajax調用實現分頁。當用戶想要查看下一個x個結果時,該頁面不應該刷新。在一個HttpResponse中返回兩件事

這是我的問題。返回QuerySet非常簡單。我只是做(sumaJson是定製)

data = serializers.serialize('sumaJson', result_page.object_list, relations=('first_major', 'country_of_origin', 'second_major')) 
return HttpResponse(data, mimetype="application/json") 

現在我還想要回東西像

result_page.has_previous() 
result_page.has_next() 
result_page.paginator.count 

等。我對於我的生活無法弄清楚如何在一個響應中獲得兩者。我無法將此信息添加到result_page.object_list,因爲序列化程序失敗。如果我的東西的那種

simplejson.dumps(paging_info + result_page.object_list) 

然後在的JavaScript的查詢集不再是對象的列表,但人物的只是一個大字符串,它不能與

$.each(data.data, function(index, item){ 

我試圖解釋一些糟糕的黑客,如創建一個虛假的對象,並將其放入object_list,序列化,然後刪除該對象。這可以讓我獲得數據。但是,我不想創建和刪除假物件。

我不想和串行染指。我不想發送第二個Ajax請求,只要我返回querySet以獲取分頁信息。

我錯過了什麼嗎?是否有一種簡單的方法可以在一個響應中獲得兩個答案?謝謝!

回答

2

當我序列化對象集合時,我通常在響應正文中包含分頁信息。如果我有50個對象,我想就可以提供10每頁中,JSON會是這個樣子:

{ 
    "count": 50, 
    "objects": [ 
     { 
      ... 
     } 
    ], 
    "pages": { 
     "count": 5, 
     "current": "http://api.example.com/objects/?page=3", 
     "first": "http://api.example.com/objects/", 
     "last": "http://api.example.com/objects/?page=5", 
     "next": "http://api.example.com/objects/?page=4", 
     "previous": "http://api.example.com/objects/?page=2" 
    } 
} 
+0

我很想做這樣的事情,但我不知道如何去到這個結構。序列化程序只能使用QuerySets和不是字典的對象列表。我可以用simplejson.dumps來做到這一點,但是我失去了進行深層序列化的能力。 – dpetters 2010-09-29 03:59:04

+1

我使用帶有自定義JSON編碼器的'simplejson.dumps'('dumps'採用可選的'cls'關鍵字參數),它負責編碼我的模型實例。 – jpwatts 2010-09-29 04:20:04

+0

我知道wadofstuff提供了一個深受歡迎的深度序列化器,但它僅適用於查詢集。任何有關建立深度序列化模型的良好JSON編碼器的建議? – dpetters 2010-09-29 16:14:58

1

我在過去對ajax調用所做的一切是將json作爲HttpResponse返回,就像您在做的那樣,併爲我想要返回的任何其他字段添加一個標頭。

data = serializers.serialize('sumaJson', result_page.object_list, relations=('first_major', 'country_of_origin', 'second_major')) 
response = HttpResponse(data, mimetype="application/json") 
response['X-VALUE'] = 'asdf' #this is the header, you can create as many of these as you'd like 
return response 

,並在JavaScript端...

$.ajax({ 
    url: '/whatever/here/', 
    success: function(data, code, xhr) { 
    alert(xhr.getResponseHeader('X-VALUE')); 
    } 
}); 

希望這會有所幫助。

+0

這可能不是最好的主意,請在另一個問題上看到這個答案。不保證HTTP頭在所有情況下都能傳送。 http://stackoverflow.com/questions/3326210/can-http-headers-be-too-big-for-browsers/3431476#3431476 – HoLyVieR 2010-09-29 03:18:49

+0

這是令人失望的,我正要說這是一個巧妙的想法。回到原來的一個...... – dpetters 2010-09-29 03:55:43

1

simplejson.dumps()能深深序列化詞典,甚至遞歸。

您可以採取兩種方法。首先是在QuerySets上使用Django ORM的values()方法:它使用對象ID生成純Python字典,而不是引用,適合序列化。

如果你需要更深入的話,你可能不得不寫一些東西來創建jpwatts提出的字典結構。如果您需要這種功能,我將have a post on my personal blog關於添加函數,生成器,迭代器和閉包給simplejson。該示例演示瞭如何將Treebeard樹結構轉換爲JavaScript對象。

的代碼是:

from django.utils.simplejson.encoder import JSONEncoder 

class ExtJsonEncoder(JSONEncoder): 
    def default(self, c): 
     # Handles generators and iterators 
     if hasattr(c, '__iter__'): 
      return [i for i in c] 

     # Handles closures and functors 
     if hasattr(c, '__call__'): 
      return c() 

     return JSONEncoder.default(self, c) 

jpwatts具有正確的做法。您可能只需編寫一些代碼即可實現。

+0

這種方法奏效。唯一痛苦的部分是自己構建json對象的結構。我的模型有很多字段。 – dpetters 2010-09-29 18:23:46

+0

有沒有什麼方法可以抽象出字段並將它們作爲通用類型的數據處理?這可能會使工作負載更輕鬆。當遇到像這樣的大數據集時,我編寫一些一行或兩行內部處理函數和一個調度表,然後用getattr()迭代字段名,將字段映射到其處理程序。在一個IDE窗格中保留每個概念單元(「如何轉換」與「要轉換的內容」)是一種有用的方法。 – 2010-09-30 16:47:43

相關問題