В чем разница между этими двумя запросами на основе Django Q: - PullRequest
1 голос
/ 17 ноября 2011

Предполагая простую модель, подобную этой:

class Item(models.Model): 
    name = models.CharField(max_length=10)

class Relation(models.Model):
    item = models.ForeignKey(Item)
    weight = models.IntegerField() 

И пару объектов типа Q, таких как:

some = Q(relation__x__gt=3)
others = Q(relation__x=7)

В чем смысловая разница между:

first = Item.objects.filter(some, ~others)

и

second = Item.objects.filter(some).exclude(others) 

ПРИМЕЧАНИЕ. Запросы через отношение, похоже, отличаются от запросов к одному простому объекту.SQL, сгенерированный для двух вышеупомянутых запросов, отличается.

Вот сгенерированный SQL для первого:

SELECT "item_item"."id", "item_item"."name" 
FROM "item_item" 
INNER JOIN "item_relation" 
ON ("item_item"."id" = "item_relation"."item_id") 
WHERE ("item_relation"."weight" > 3  
  AND NOT ("item_item"."id" IN 
    (SELECT U1."item_id" 
     FROM "item_relation" U1 
     WHERE (U1."weight" = 7  AND U1."item_id" IS NOT NULL))))

И SQL для второго:

SELECT "item_item"."id", "item_item"."name" 
FROM "item_item" 
INNER JOIN "item_relation" 
ON ("item_item"."id" = "item_relation"."item_id") 
INNER JOIN "item_relation" T3 
ON ("item_item"."id" = T3."item_id") 
WHERE ("item_relation"."weight" > 3  AND NOT (T3."weight" = 7 ))
...