Django filter vs exclude

Is there a difference between filter and exclude in django? If I have

self.get_query_set().filter(modelField=x)

and I want to add another criteria, is there a meaningful difference between to following two lines of code?

self.get_query_set().filter(user__isnull=False, modelField=x)

self.get_query_set().filter(modelField=x).exclude(user__isnull=True)

is one considered better practice or are they the same in both function and performance?


Solution 1:

Both are lazily evaluated, so I would expect them to perform equivalently. The SQL is likely different, but with no real distinction.

Solution 2:

It depends what you want to achieve. With boolean values it is easy to switch between .exclude() and .filter() but what about e.g. if you want to get all articles except those from March? You can write the query as

Posts.objects.exclude(date__month=3)

With .filter() it would be (but I not sure whether this actually works):

Posts.objects.filter(date__month__in=[1,2,4,5,6,7,8,9,10,11,12])

or you would have to use a Q object.

As the function name already suggest, .exclude() is used to exclude datasets from the resultset. For boolean values you can easily invert this and use .filter() instead, but for other values this can be more tricky.

Solution 3:

In general exclude is opposite of filter. In this case both examples works the same.

Here:

self.get_query_set().filter(user__isnull=False, modelField=x)

You select entries that field user is not null and modelField has value x

In this case:

self.get_query_set().filter(modelField=x).exclude(user__isnull=True)

First you select entries that modelField has value x(both user in null and user is not null), then you exclude entries that have field user null.

I think that in this case it would be better use first option, it looks more cleaner. But both work the same.