@NyxDeveloper

Фильтрация DjangoFilterBackend по нескольким значениям?

Возникла необходимость фильтровать queryset по нескольким значениям одного и того же поля, но при отправке в запросе значений /?v=1&v=2 джанга фильтрует по последнему переданному значению, то есть по v=2.
Я использую ViewSets + DjangoFilterGenerics:
class ProjectViewSet(viewsets.ModelViewSet):
    permission_classes = [IsAuthenticated, ProjectsPermission]
    serializer_class = ProjectSerializer
    extra_serializer_class = ProjectOptSerializer
    queryset = Project.objects.all()
    pagination_class = StandardResultsSetPagination
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]

    filterset_fields = [
        'id', 'counterparty', 'participant', 'project_type', 'status', 'funding_source', 'quarter', 'team',
        'date_contract', 'date_delivery_contract', 'date_gk_contract', 'date_delivery', 'date_commissioning',
        'approved', 'employee_init', 'is_archive'
    ]
    search_fields = [
        'title', 'amount_planned', 'counterparty__short_name', 'counterparty__full_name', 'participant__short_name',
        'participant__full_name', 'project_type__title', 'status__title', 'funding_source__title', 'quarter__title',
        'team__title', 'implementation', 'date_contract', 'date_delivery_contract', 'date_gk_contract', 'date_delivery',
        'date_commissioning', 'employee_init__first_name', 'employee_init__last_name', 'employee_init__middle_name'
    ]
    ordering_fields = search_fields + filterset_fields


Пробовал залесть дебагером внутрь и посмотреть что там происходит, после предпринял следующее:
filterset_fields = {
        'id': ['in', 'exact'], 'counterparty': ['in', 'exact'], 'participant': ['in', 'exact'],
        'status': ['in', 'exact'], 'funding_source': ['in', 'exact'], 'quarter': ['in', 'exact'],
        'project_type': ['in', 'exact'], 'team': ['in', 'exact'], 'date_contract': ['exact'],
        'date_delivery_contract': ['exact'], 'date_gk_contract': ['exact'], 'date_delivery': ['exact'],
        'date_commissioning': ['exact'], 'employee_init': ['in', 'exact'], 'is_archive': ['exact'],
        'approved': ['exact']
    }


Такой вариант не работает. Если убрать 'in', то работает как и в варианте выше.
Искал ответ в сети, там пишут про MultipleChoiceFilter, но его проблема в том, что ему нужно прописывать чойзы, а это не то что мне нужно.
Подскажите как можно менее велосипедно решить данную задачу, пожалуйста!
  • Вопрос задан
  • 700 просмотров
Пригласить эксперта
Ответы на вопрос 1
@NyxDeveloper Автор вопроса
В качестве временной меры был предпринят следующий костыль в методе get_queryset:
def get_queryset(self):
        qs = self.queryset
        if len(self.request.query_params) > 0:
            for p in self.request.query_params:
                for f in self.filterset_fields:
                    if p == f:
                        qs = qs.filter(**{'%s__in' % f: self.request.query_params.getlist(p)})
        return qs

Я не считаю это достаточно подходящим решением, т.к. код слишком плосский, его не вынести в отдельную функцию и вообще он мне не нравится, поэтому вопрос все еще открыт. Прошу не обделять вниманием, пожалуйста.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы