2017-10-18 241 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

我的解决方案是您建议和使用列表的方法的组合。但是你的评论是正确的,该项目在代码组织方面演变得相当奇怪。 –

相关问题