Search code examples
django-orm

Django ORM - Select All Records from One Table That Do Not Exist in Another Table


Lets have 2 models:

class A(models.Model):
    f1 = models.CharField()
    f2 = models.IntegerField()
    f3 = models.BooleanField()


class B(models.Model):
    f1 = models.CharField()
    f2 = models.IntegerField()
    f3 = models.DecimalField()

Lets have this data:

A(f1=rat, f2=100, f3=true)
A(f1=cat, f2=200, f3=true)
A(f1=dog, f2=300, f3=false)
B(f1=eagle, f2=100, f3=3.14)
B(f1=cat, f2=200, f3=9.81)
B(f1=dog, f2=300, f3=100.500)

I need to select objects from table B, that does not have similar data for fields f1, f2 in table A.

In my case it will be:

B(f1=eagle, f2=100, f3=3.14)

The following objects are not relevant, because they exist in both tables (f1 and f2 fields)

B(f1=cat, f2=200, f3=9.81)
B(f1=dog, f2=300, f3=100.500)

Is it possible to select this data using Django ORM?

I tried to find information about Sub-query, but did not find good example.


Solution

  • resolved in this way:

    from django.db.models import OuterRef, Exists    
    
    a_queryset = A.objects.filter(f1=OuterRef('f1'), f2=OuterRef('f2'))
    
    result_queryset = B.objects.filter(~Exists(a_queryset))
    # B(f1=eagle, f2=100, f3=3.14)
    

    reverse:

    result_queryset = B.objects.filter(Exists(a_queryset))
    # B(f1=cat, f2=200, f3=9.81)
    # B(f1=dog, f2=300, f3=100.500)