Skip to main content
 首页 » 编程设计

python之django-rest-framework 中字段的单独搜索过滤器

2024年12月31日2252php

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 元组中,它会在both 中查找相同的搜索字符串。

有没有一种方法可以单独定义这些搜索字段,让我可以执行以下操作:

?search_symbol=AMZ&search_name=Good 以便它查找在 symbol 字段中具有 AMZ 且 good 的对象> 在 name 字段中?

请您参考如下方法:

要实现这一点,您需要一个扩展 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 

现在用您的 View filter_backends 中的新 CustomSearchFilter 替换 filters.SearchFilter。

希望这对您有所帮助,我是在没有亲自测试代码的情况下编写的,所以请告诉我您的进展情况!