[Django]-Django queryset EXCLUDE: are these equivalent?

9πŸ‘

βœ…

The two are not equivalent.

As is specified in the documentation on exclude(..):

The lookup parameters (**kwargs) should be in the format described in Field lookups below. Multiple parameters are joined via AND in the underlying SQL statement, and the whole thing is enclosed in a NOT().

So the first query can be read as:

-- first query
SELECT car.*
FROM car
WHERE NOT (brand = 'mercedes') AND NOT (YEAR <= 2000)

whereas the latter is equivalent to:

-- second query
SELECT car.*
FROM car
WHERE NOT (brand = 'mercedes' AND YEAR <= 2000)

The first query this is semantically the same as β€œAll cars that are not a Mercedes; and that are not build before or in the year 2000β€œ. Whereas the second query is β€œAll cars except Mercedeses that are built before or in the year 2000.β€œ.

So in case the table contains a Ford that is built in 1993, then the first query will not include it, whereas the second will, since the brand is not Mercedes, it is not excluded (so it will be part of the queryset).

Leave a comment