'Use django_filters to query a list that contains any item in query params

I'm having a Django model that contains a JSON field to store a list, like so:

class Movie(models.Model):
    tags = JSONField()

As such, a movie mymovie contains a list of tags, such as:

mymovie.tags = ["horror", "love", "adventure"].

And now, I want a query to fetch all movies having at least one tag of a list of tags, like so:

GET /movies?tags=horror,cowboy

In my previous example, the query will get mymovie, because it has horror in its tag, even if it doesn't have cowboy.

Using *django_filters, I managed to do it with the following implementation:

class CharInFilter(BaseInFilter, CharFilter):
    pass

class MovieFilter(FilterSet):

    class Meta:
        model = Movie
        fields = ["tags"]

    tags = CharInFilter(method="tags_filter")

    def tags_filter(self, queryset, name, value):
        # value will contain a list of tags, and we want any movie that at least one of
        # its tag is in the list of provided tags
        query = Q()
        for tag in value:
            query |= Q(
                tags__icontains=tag
            )
        if query:
            queryset = queryset.filter(query)
    
        return queryset

It works, but it feels very hacky, and I won't be surprised if an ad hoc implementation of this exists.

Does someone have a better idea ?

Thank youuuu ^^



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source