Django in / not in query
table1.objects.exclude(id__in=
table2.objects.filter(your_condition).values_list('id', flat=True))
The exclude function works like the Not
operator you where asking for. The attribute flat = True
tells to table2
query to return the value_list
as a one level list. So... at the end you are obtaining a list of IDs
from table2, which you are going to user to define the condition in table1
, that will be denied by the exclude function.
table1.objects.extra(where=["table1.id NOT IN (SELECT table2.key_to_table1 FROM table2 WHERE table2.id = some_parm)"])
with these models:
class table1(models.Model):
field1 = models.CharField(max_length=10) # a dummy field
class table2(models.Model):
key_to_table1 = models.ForeignKey(table1)
you should get what you want using:
table1.objects.exclude(table2=some_param)
The accepted answer is ok but I'm going to provide a new approach which is more operable.
from django.db.models import Q
query = Q(id__in=table2.objects.filter(your_condition).values_list('id'))
table1.objects.filter(~query)
If you are using the primary key the call to values_list() is not necessary.
The "~" on Q() object acts like "not" operator.
I guess this approach makes the code more reusable and allows you to do "any" sort of dynamic stuff just by storing your Q() objects on vars.