2017-10-18 239 views
0

我需要將來自不同模型的兩個Queryset合併爲一個。最建議的解決方案,我發現網上有:如何將兩個Queryset合併成不同的模型?

要使用|&,但是這隻能在查詢集從相同的模型

要使用chainlist,但這帶走一些查詢集方法,並且由於我的項目中的代碼的結構方式,我不能改變它。我試過了,沒有工作。

我讀了約Q,但我不清楚我如何應用它來實現我所需要的。

基本上我需要將來自不同模型的兩個查詢集合到第三個查詢集中,而不是列表中。他們共享一些字段名稱,可能對Q有用。在例如:

queryset_1 = Cars.objects.all().filter(color='red') 
queryset_2 = Horses.objects.all() 

queryset_3 = queryset_1 + queryset_2 

queryset_3.order_by('date') 
+0

你不能做到這一點。定義的查詢集是來自單個模型的一組對象。 –

回答

1

你不能在數據庫或查詢集級別做到這一點,因爲不幸的是這兩件事情並不在同一個數據庫表中。你可以在python方面做到這一點(雖然速度更慢,計算量更大)。

假設這兩款車和馬有一個「日期」的屬性,你可以這樣做:

cars = Cars.objects.all().filter(color='red') 
horses = Horses.objects.all() 
all_things = list(cars) + list(horses) 
sorted_things = sorted(all_things, key=lambda x: x.date) 

另一種選擇(這是在數據庫級別低效率),將讓他們都來自同一個繼承非抽象模型。

class Item(models.Model): 
    date = models.DateTimeFiedl() 
    item_type = models.CharField(max_length=255) 

    def get_instance(self): 
     if self.item_type = 'car': 
      return Car.objects.get(id=self.id) 
     elif self.item_type == 'horse': 
      return Horse.objects.get(id=self.id) 

class Car(Item): 
    color = models.CharField(max_length=12) 

    def save(self, *args, **kwargs): 
     self.item_type = 'car' 
     super(Car, self).save(*args, **kwargs) 

class Horse(Item): 
    breed = models.CharField(max_length=25) 

    def save(self, *args, **kwargs): 
     self.item_type = 'horse' 
     super(Horse, self).save(*args, **kwargs) 

有了這一點,你可以做

items = Item.objects.all().order_by('date') 
for item in items: 
    print(type(item)) # Always "Item" 
    actual_item = item.get_instance() 
    if type(actual_item) == Car: 
     print("I am a car") 
    else: 
     print("I am a horse") 

在遍歷他們需要抓住每一個具體的項目(類似於鶺鴒如何處理頁面,您爲抓取對象的便捷方法,基於其父類)

2

如果你真的需要這樣的查詢集,這可能是模型設計不正確的一個症狀,任何快速修復可能比修改模型更繁瑣。我的建議是建立一個取代汽車和馬匹的單一模型(即使某些字段在每個案例中都會保持空白),並且有一個單獨的字段,以便您輕鬆識別這兩個字段。例如:

class Vehicle(models.Model): 
    category = models.IntegerField(
     choices=[(10, 'Horse'), (20, 'Car'), (30, 'Bicycle')] 
    ) 
    # other fields here... 
+0

我的意思是數據庫規範化: https://en.wikipedia.org/wiki/Database_normalization – White

+0

正確!就是這樣。 – davecaputo

+0

我的解決方案是您建議和使用列表的方法的組合。但是你的評論是正確的,該項目在代碼組織方面演變得相當奇怪。 –

相關問題