Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django queryset EXCLUDE: are these equivalent?

In Django, are these two equivalent?

Cars.objects.exclude(brand='mercedes').exclude(year__lte=2000)

and

Cars.objects.exclude(brand='mercedes', year__lte=2000)

?

I know the first one says: exclude any mercedes and exclude any car older than year 2000. What about the second one? Does it say the same? Or it does only exclude the combination of mercedes being older than year 2000?

Thanks!

like image 493
jobima Avatar asked Mar 28 '26 16:03

jobima


1 Answers

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).

like image 156
Willem Van Onsem Avatar answered Mar 30 '26 11:03

Willem Van Onsem



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!