Add a django-filter to allow contains, match (exact) and exclude certain text

376 Views Asked by At

Based on the documentation for django-filters to use excludes I have a filter that allows custom filtering for multiple fields to search to match text (exact or contains). I'm trying to extend this to allow the text to be excluded from the search. i.e search for columns NOT containing text.

This is not what I want to do, I want the filter to essentially work like:

Table.filter(col1__contains='text', col2='text2').exclude(col3='text3')

Similar to but need an example that works for exact, matching and exclusive searches. How to use Django filter's exclude argument with user input?

1

There are 1 best solutions below

1
On

You probably want to use a custom filter method:

class MyFilter(FilterSet):
    text = CharFilter(method='filter_published')

    def filter_published(self, queryset, name, value):
        return queryset.fitler(col1__exact=value).exclude(col3__contains=value)

    class Meta:
        model = Book
        fields = ['published']

You can also wrap it all up in a custom filter field if you intended to re-use it, something like this (untested):

class FancyCharFilter(CharFilter):
    def __init__(include_fields, exclude_fields): 
        self.include_fields = include_fields
        self.exclude_fields = exclude_fields

    def filter(self, queryset, name, value):
        for field in self.include_fields:
            queryset = queryset.filter(**{field: value})
        for field in self.exclude_fields:
            queryset = queryset.exclude(**{field: value})
        return queryset
        
class MyFilter(BaseFilter):
    text = FancyCharFilter(
        include_fields=["col1__exact", "col2__contains"],
        exclude_fields=["col3__contains"]
    )