Я пытаюсь понять, как написать запрос "не в стиле" в 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?
Ответ 1
table1.objects.exclude(id__in =
table2.objects.filter(your_condition).values_list('id', flat=True))
Функция exclude работает как оператор Not
, в котором вы запрашиваете. Атрибут flat = True
сообщает table2
запросу, чтобы вернуть value_list
в виде списка одного уровня. Итак... в конце вы получаете список IDs
из таблицы2, который вы собираетесь определить пользователем в table1
, который будет отклонен функцией exclude.
Ответ 2
с этими моделями:
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)
Ответ 3
table1.objects.extra(where=["table1.id NOT IN (SELECT table2.key_to_table1 FROM table2 WHERE table2.id = some_parm)"])
Ответ 4
Вы можете написать собственный поиск для запросов Django:
Из документация:
"Давайте начнем с простого пользовательского поиска. Мы напишем пользовательский поиск ne, который работает против точного. Author.objects.filter(name__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
Ответ 5
[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]