如何在Django queryset中创建Union

时间:2014-04-16 13:18:02

标签: django django-rest-framework

我在项目中使用Django REST Framework,我想创建两个不同模型的union。

我的模特

class A(models.Model):
    name = models.CharField(max_length=240, blank=True)
    geometry = models.GeometryField(blank=True, null=True)
    abwrapper= models.ForeignKey(ABWrapper)

    class Meta:
        db_table = 'tbl_a'

class B(models.Model):
    name = models.CharField(max_length=240, blank=True)
    link = models.IntegerField(blank=True, null=True)
    geometry = models.GeometryField(blank=True, null=True)
    abwrapper= models.ForeignKey(ABWrapper)

    class Meta:
        db_table = 'tbl_b'

我正在尝试创建此查询

SELECT id,name FROM tbl_a UNION (SELECT b.id,b.name From tbl_b b)

我尝试结合

a = A.objects.values_list('id')
b = B.objects.values_list('id')
queryset = a | b

Error:
AssertionError: Cannot combine queries on two different base models.

现在我以这种方式尝试使用父模型

class ABWrapper(models.Model):
    objects = models.GeoManager()
    class Meta:
        db_table = u'ab_wrapper'

在两个模型

上方添加了此模型作为ForeignKey
a = ABWrapper.objects.filter(a__isnull=False).values('a__id')
b = ABWrapper.objects.filter(b__isnull=False).values('b__id')
queryset = a | b

Error:
TypeError: Merging 'GeoValuesQuerySet' classes must involve the same values in each case.

制作别名的另一种尝试

a = ABWrapper.objects.filter(a__isnull=False).extra(select={'tempID':'a__id'}).values_list('tempID')
b = ABWrapper.objects.filter(b__isnull=False).extra(select={'tempID':'b__id'}).values_list('tempID')
queryset = a | b

Error:
ValueError: When merging querysets using 'or', you cannot have extra(select=...) on both sides.

我已经对它进行了搜索,主要回答了这个问题,就像使用两个模型的列表一样。但我不想使用list,因为我正在使用Django Rest Framework,所以我需要QuerySet。所以我的问题是,如果我使用list for union,我可以将结果列表转换为QuerySet。

注意:我不想在Django中使用SQL Query

还有其他办法可以完成这项任务吗?

1 个答案:

答案 0 :(得分:1)

您可以在django中使用Q对象进行复杂过滤。查看this_link了解实现细节。