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。
希望这对您有所帮助,我是在没有亲自测试代码的情况下编写的,所以请告诉我您的进展情况!
