4

I am using Django REST Framework in project and I want to create union two different Models.

My Models

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'

I am trying to create this query

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

My attempt for union

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.

Now i tried with parent Model in this way

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

Added this model as ForeignKey above both Models

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.

Another attempt by making alias

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.

I have searched on it, mostly answered this issue as using list for both models. But I don't want to use list as I am using Django Rest Framework so I need QuerySet. So my question if I use list for union can I convert resulting list into QuerySet.

Note: I don't want to use SQL Query in Django

Is there any other way to do this task?

Shoaib Ijaz
  • 5,347
  • 12
  • 56
  • 84
  • look http://stackoverflow.com/questions/3300735/django-union-of-different-queryset-on-the-same-model – user3535644 Apr 16 '14 at 19:32
  • Above question does not return queryset – Shoaib Ijaz Apr 17 '14 at 07:58
  • from django.db.models import Q queryset = ABWrapper.objects.filter(Q(a__isnull=False)|Q(b__isnull=False)` does not work ? – user3535644 Apr 18 '14 at 05:19
  • 1
    Very late to the party, but I ran into this and ended up writing a little wrapper.. https://pypi.python.org/pypi/django-compoundqueryset – bwawok Jul 10 '16 at 21:01
  • Possible duplicate of [How can I find the union of two Django querysets?](https://stackoverflow.com/questions/4411049/how-can-i-find-the-union-of-two-django-querysets) – Aaron McMillin Aug 15 '17 at 03:52
  • 1.11 added .union() to QuerySet, see the answer here: https://stackoverflow.com/questions/4411049/how-can-i-find-the-union-of-two-django-querysets – Aaron McMillin Aug 15 '17 at 03:53

1 Answers1

1

You can use Q objects in django for complex filtering.Look at this_link for implementation details.

Amrit
  • 2,115
  • 1
  • 21
  • 41