Как добавить несколько фильтров при использовании фреймворка Django Rest search_filter
В настоящее время я пытаюсь создать сайт на основе фуллстэка, используя django для бэкенда. Одной из функций, которую я создаю, является функция поиска. Для этого я использовал встроенный в django-rest SearchFilter, а также встроенный OrderingFilter, чтобы пользователи могли переключать порядок результатов. Однако я также хочу, чтобы пользователи могли фильтровать результаты, например, выбирать конкретный год или конкретное имя из выпадающего меню. То есть, по сути, я хочу иметь возможность использовать фильтр поиска и при этом указать другое поле, которое должно точно соответствовать. Например, допустим, пользователи искали "Cat" и результаты были следующими:
Имя: Cat1
Описание: Счастливый кот
Год: 2017
Имя: Cat2
Описание: Грустный кот
Год: 2017
Имя: Лев
Описание: Крупная кошка
Год: 2018
Имя: Лев
Описание: Крупная кошка
Год: 2019
Все эти результаты отображаются, поскольку содержат "cat" в полях name или description. Но затем я хочу, чтобы пользователь мог указать год через выпадающее меню. Таким образом, меню будет содержать 2017, 2018 и 2019 годы в качестве вариантов, и после выбора 2017 года результаты будут выглядеть следующим образом:
Имя: Cat1
Описание: Счастливый кот
Год: 2017
Имя: Cat2
Описание: Грустный кот
Год: 2017
С отфильтрованными другими годами. Я не могу сделать это на фронт-энде, потому что база данных, с которой я работаю, содержит тысячи записей, что означает, что результаты возвращаются в виде страниц. Эта проблема кажется довольно простой, но ничего из того, что я пробовал, не помогло. Кто-нибудь знает лучший способ решения этой проблемы?
Вот модель базы данных для объектов, по которым ведется поиск:
class Measure(OverrideModel):
year = models.ForeignKey(Year, on_delete=models.PROTECT)
name = models.CharField(max_length=200)
description = models.TextField()
class Meta:
constraints = [
models.UniqueConstraint(
fields=["duration", "code"],
name=prefix("measure", "duration_code_uniq"),
)
]
А вот текущий вид, который я использую:
class MeasureSearchViewSet(viewsets.ReadOnlyModelViewSet):
queryset = models.Measure.objects.all()
serializer_class = serializers.MeasureSerializer
filter_backends = [OrderingFilter, SearchFilter]
search_fields = ["name", "description"]
ordering_fields = ["duration", "name"]
def get_serializer(self, *args, **kwargs):
return super().get_serializer(
*args, program=self.program, tag=False, **kwargs
)
Любой совет был бы признателен, спасибо :)
Вам необходимо объединить механизмы поиска и фильтрации. Помимо определения search_fields Вам необходимо добавить filter_fields атрибут к Вашему ViewSet:
class MeasureSearchViewSet(viewsets.ReadOnlyModelViewSet):
queryset = models.Measure.objects.all()
serializer_class = serializers.MeasureSerializer
filter_backends = [OrderingFilter, SearchFilter]
search_fields = ["name", "description"]
ordering_fields = ["duration", "name"]
filterset_fields = ['year'] # enable filtering by year
def get_serializer(self, *args, **kwargs):
return super().get_serializer(
*args, program=self.program, tag=False, **kwargs
)
Подробную информацию можно получить на: https://www.django-rest-framework.org/api-guide/filtering/#generic-filtering