Индивидуальные поисковые фильтры для полей в django-rest-framework - PullRequest
0 голосов
/ 18 января 2019

Django-rest-framework будет иметь SearchFilter бэкэнд, который позволит один запрос к полям поиска:

class OrganizationViewSet(viewsets.ModelViewSet):
    queryset = Organization.objects.all()
    serializer_class = OrganizationSerializer
    pagination_class = CustomPagination
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    filter_fields = ('sector', 'industry', 'marketplace')
    search_fields = ('symbol',)

таким образом, когда я запрашиваю ...?search=AMZ, он будет возвращать только записи с нечувствительным совпадением в поле symbol.

Если я добавлю еще один элемент в кортеж search_fields, он будет искать эту же строку поиска в обоих .

Есть ли способ определить эти поля поиска индивидуально, что позволит мне сделать что-то вроде:

?search_symbol=AMZ&search_name=Good, так что он ищет объекты, которые имеют AMZ в поле symbol и good в name поле?

1 Ответ

0 голосов
/ 18 января 2019

Для этого вам понадобится пользовательский бэкэнд фильтра, расширяющий класс rest_framework.filters.SearchFilter. В частности, в классе rest_framework.filters.SearchFilter есть метод get_search_terms:

    def get_search_terms(self, request):
        """
        Search terms are set by a ?search=... query parameter,
        and may be comma and/or whitespace delimited.
        """
        params = request.query_params.get(self.search_param, '')
        return params.replace(',', ' ').split()

Мы можем переопределить этот метод в нашем собственном классе CustomSearchFilter, чтобы контролировать, как вы определяете условия поиска в URL, например:

class CustomSearchFilter(SearchFilter):
    search_field_prefix = "search_"

    def get_search_terms(self, request):
        # get search fields from the class
        search_fields = getattr(request.resolver_match.func.view_class, 'search_fields', list())

        params = []

        # iterate over each query paramater in the url
        for query_param in request.query_params:

            # check if query paramater is a search paramater
            if query_param.startswith(CustomSearchFilter.search_field_prefix):

                # extrapolate the field name while handling cases where <CustomSearchFilter.search_field_prefix> is in the field name
                field = CustomSearchFilter.search_field_prefix.join(
                    query_param.split(CustomSearchFilter.search_field_prefix)[1:]
                )

                # only apply search filter for fields that are in the views search_fields
                if field in search_fields:
                    params.append(request.query_params.get(query_param, ''))

        return params

Теперь замените filters.SearchFilter на ваш новый CustomSearchFilter в ваших представлениях filter_backends.

Надеюсь, это поможет, я написал это, не тестируя сам код, поэтому дайте мне знать, как у вас дела!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...