Используйте django_filters для запроса списка, содержащего любой элемент в параметрах запроса

У меня есть модель Django, которая содержит поле JSON для хранения списка, примерно так:

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

Как таковой, фильм mymovie содержит список тегов, таких как:

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

А теперь я хочу, чтобы запрос получил все фильмы, имеющие хотя бы один тег из списка тегов, например, так:

GET /movies?tags=horror,cowboy

В моем предыдущем примере запрос получит mymovie, потому что в его теге есть horror, даже если в нем нет cowboy.

Используя *django_filters, мне удалось сделать это со следующей реализацией:

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

Это работает, но это кажется очень халтурным, и я не удивлюсь, если существует специальная реализация этого.

У кого-то есть идея получше?

Спасибо ^^

Вернуться на верх