Skip to content Skip to sidebar Skip to footer

Exclude Vs Filter, When Using Q Objects

Can't understand how this is possible: A = object_list.filter( Q(sales__sale_starts__lte=today) & Q(sales__sale_ends__gte=today) ) # query inside filter catches 2 objects B =

Solution 1:

The behavior should be the same. If you look at .exclude() and .filter() source code, they do the same:

defexclude(self, *args, **kwargs):
    """
    Returns a new QuerySet instance with NOT (args) ANDed to the existing
    set.
    """return self._filter_or_exclude(True, *args, **kwargs)

deffilter(self, *args, **kwargs):
    """
    Returns a new QuerySet instance with the args ANDed to the existing
    set.
    """return self._filter_or_exclude(False, *args, **kwargs)

And _filter_or_exclude() just negate your Q filter with ~

def _filter_or_exclude(self, negate, *args, **kwargs):
    if args or kwargs:
        assert self.query.can_filter(), \
            "Cannot filter a query once a slice has been taken."

    clone = self._clone()
    if negate:
        clone.query.add_q(~Q(*args, **kwargs))
    else:
        clone.query.add_q(Q(*args, **kwargs))
    return clone

Solution 2:

As @PauloAlmeida said

The multi-valued result may be the issue, see these two bug reports: Exclude query with multiple conditions for the same multi-value relation not correct; Problem with negating Q object.

So there is indeed can be a difference between filter() and exclude(), because of different sql generation. And maybe bugs in exclude().

Post a Comment for "Exclude Vs Filter, When Using Q Objects"