簡體   English   中英

如何將來自不同模型的兩個查詢集組合為一個?

[英]How to combine two Querysets into one from different models?

我需要將來自不同模型的兩個查詢集組合為一個。 我在網上找到的最建議的解決方案是:

使用| & ,但這僅適用於同一模型的查詢集

要使用chainlist ,但這會占用一些queryset方法,並且由於我項目中代碼的結構方式,我無法更改它。 我試過了,沒有用。

我讀到有關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')

如果您確實需要這樣的查詢集,這可能是模型設計不正確的征兆,冒着任何快速修復都可能比重新構建模型更加繁瑣的風險。 我的建議是建立一個單獨的模型來替換Car和Horse(即使對於每個案例的實例某些字段仍然為空),並使用單獨的字段可以輕松識別兩者。 例如:

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

不幸的是,您不能在數據庫或查詢集級別上執行此操作,因為這兩個功能在同一數據庫表中不存在。 您可以在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")

在遍歷它們的同時,根據需要捕獲每個特定的項(類似於Wagtail處理頁面的方式,您可以根據其父類提供一種便捷的方法來捕獲對象)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM