Django в / не в запросе


Я пытаюсь выяснить, как написать запрос стиля "не в" в django. Например, структура запроса, о которой я думаю, будет выглядеть так.

select table1.* 
from table1
where table1.id not in 
(
  select table2.key_to_table1
  from table2 
  where table2.id = some_parm 
)

как бы выглядел синтаксис django, если бы модели назывались table1 и table2?

5 81

5 ответов:

table1.objects.exclude(id__in = table2.objects.filter(your_condition).values_list('id', flat=True))

функция exclude работает как

С этими моделями:

class table1(models.Model):
    field1 = models.CharField(max_length=10)      # a dummy field

class table2(models.Model):
    key_to_table1 = models.ForeignKey(table1)

вы должны получить то, что вы хотите использовать:

table1.objects.exclude(table2=some_param)
table1.objects.extra(where=["table1.id NOT IN (SELECT table2.key_to_table1 FROM table2 WHERE table2.id = some_parm)"])

Вы можете написать пользовательский поиск для запросов в Django:

С документация: "Давайте начнем с простого пользовательского поиска. Мы напишем пользовательский поиск ne который работает напротив точно. автор.объекты.фильтр (имя_ _ ne= 'Jack') переведет на SQL:"author"."name" <> 'Jack'"

from django.db.models import Lookup

class NotEqual(Lookup):
    lookup_name = 'ne'

    def as_sql(self, compiler, connection):
        lhs, lhs_params = self.process_lhs(compiler, connection)
        rhs, rhs_params = self.process_rhs(compiler, connection)
        params = lhs_params + rhs_params
        return '%s <> %s' % (lhs, rhs), params
[o1 for o1 in table1.objects.all() if o1.id not in [o2.id for o2 in table2.objects.filter(id=some_parm)]]

или лучше

not_in_ids = [obj.id for obj in table2.objects.filter(id=some_parm)]
selected_objects = [obj for obj in table1.objects.iterator() if obj.id not in not_in_ids]