2016-09-16 54 views
1

我一直在研究這幾天。不幸的是,迄今爲止我發現的所有建議解決方案都不適合我。手動合併多個Django查詢集,並使用DRF序列化結果

我正在尋找手動將兩個Django QuerySets組合成單個Django模型,然後我想使用Django Rest Framework序列化器進行序列化。然後我使用串行器輸出JSON。

我已經找到了各種解決方案,建議使用itertools和鏈,但不清楚如何序列化鏈的結果。

請注意,我的目標是用於Web應用程序性能目的。每個QuerySet都能獨立工作,但它需要兩個獨立的Ajax調用來檢索結果。我寧願只進行一次Ajax調用,手動合併服務器端的結果,然後返回組合的JSON。

這個SO答案是接近的,但我不知道如何使用DRF序列化器序列化鏈的結果。

回答

1

來自同一模型的兩個查詢集?如果是這樣,你可以說:

qs1 = Potato.objects.filter(size = PotatoSize.large) 
qs2 = Potato.objects.filter(color = VegetableColor.brown) 
combined_qs = qs1 | qs2 

如果它們來自不同的模型,但這些模型是通過繼承(即一個是一個抽象類),你仍然可以做到這一點的相互關係:

qs1 = RootVegetable.objects.filter(color = VegetableColor.brown) 
qs2 = Potato.objects.filter(size = PotatoSize.large) 

qs2.model = RootVegetable 

# this will return a QS of RootVegetables 
combined_qs = qs1 | qs2 

然後,您可以序列化組合的查詢集。

+0

的模型是相關的,但一個是不是其他的一個抽象類。基本上,我需要一種方法將兩個QuerySets附加到單個模型,然後序列化整個事物。而且這個單一模型是一個非託管模型(即沒有相應的數據庫表)。基本上我試圖將幾組相關的數據組合在一起。不幸的是,這個建議並沒有太多幫助。 –

+0

我添加了一個鏈接到SO關閉的答案。它只是沒有解釋如何序列化結果,特別是當我序列化的模型不受管理時。 –

2

經過幾天的谷歌搜索這個問題的答案,我終於偶然發現this page,這解釋瞭如何做我想做的事情。如果別人有同樣的問題,我在這裏發佈了自己的答案。

這個技術現在看起來很簡單,我明白了,但我很難在網上找到任何描述這種技術的東西。基本上,您將多個查詢集合在一起,然後將鏈轉換爲Python列表。然後迭代列表,手動調用正確的序列化程序,並追加到字典中。然後,您可以將字典轉儲爲JSON。

我已經發布了相關的代碼的情況下,該鏈接去死:

def get_queryset(self): 
     queryset_a = Post.objects.all() 
     queryset_b = FriendRequest.objects.filter(is_unanswered=True) 

     # Create an iterator for the querysets and turn it into a list. 
     results_list = list(chain(queryset_a, queryset_b)) 

     # Optionally filter based on date, score, etc. 
     sorted_list = sorted(results_list, key=lambda instance: -instance.date_created) 

     # Build the list with items based on the FeedItemSerializer fields 
     results = list() 
     for entry in sorted_list: 
      item_type = entry.__class__.__name__.lower() 
      if isinstance(entry, Post): 
       serializer = PostSerializer(entry) 
      if isinstance(entry, FriendRequest): 
       serializer = FriendRequestSerializer(entry) 

      results.append({'item_type': item_type, 'data': serializer.data}) 

     return results