philipn/django-rest-framework-filters

Filter.method not support negation/exclusion

gustabot42 opened this issue · 1 comments

The actual signature of filter method does not permit to resolve automatic filter negations !=.
Automatic filter negation depends on the exclude attribute but this attribute is not accessible with the actual filter method signature.
A possible solution is to change the signature from (qs, name, value) to (qs, name, value, exclude)

class FilterMethod(object):
    def __call__(self, qs, value):
        if value in EMPTY_VALUES:
            return qs
        return self.method(qs, self.f.field_name, value, self.f.exclude)

Hi @gustabot42. Good catch. I've opened carltongibson/django-filter#1150 to track this.

As a workaround, you could use partialmethod to bind the filter attribute name to the method, then lookup the filter and its attributes from there. e.g.,

class MyFilter(FilterSet):
    date = IsoDateFilter(field_name='f', lookup_expr='exact', method='date_filter')
    not_date = IsoDateFilter(field_name='f', lookup_expr='exact', exclude=True, method='not_date_filter')

    def generic_date_filter(self, qs, field_name, value, attr):
        f = self.filters[attr]
        # do something with `f.exclude`
    
    date_filter = partialmethod(generic_date_filter, attr='date')
    not_date_filter = partialmethod(generic_date_filter, attr='not_date')

That said, closing as this is an issue with django-filter and not DRFF.