【问题标题】:Django DRF - using basic search filter to do an multiple OR searchDjango DRF - 使用基本搜索过滤器进行多重 OR 搜索
【发布时间】:2020-01-01 14:58:36
【问题描述】:

我正在尝试使用基本的 Django 过滤器进行多重 OR 搜索。我已经尝试过以下 URL,但它们只返回第一个结果

api/电路/?search=AB5814765;AB827451;AB0923784

使用逗号也不返回任何结果。

是否有任何语法会显示内置的多个记录或做一些自定义需要制作的东西,我尝试了一些自定义尝试,但它们也都失败了

当我尝试执行以下操作时,会出现 404 错误

api/电路/ref_search/AB5814765|AB827451|AB0923784

@action(detail=False, methods=['get'], url_path='ref_search/(?P<refs>[^/.]+)/', permission_classes=[IsAdminUser])
def ref_search(self, request, refs, *args, **kwargs):
    refs = refs.split('|')
    query = Q()
    for x in refs:
        q = Q(circuit__ref_no=x)
        query |= q
    queryset = DeviceCircuitSubnets.objects.filter(query)
    serializer = self.serializer_class(queryset, many=True)
    return Response(data=serializer.data)  

我也试过了

api/电路/ref=AB5814765|AB827451|AB0923784

def get_queryset(self):
    refs = self.request.query_params.get('ref', None)
    if refs is not None:
        refs = refs.split('|')
        query = Q()
        for x in refs:
            q = Q(status=x)
            query |= q
        queryset = queryset.filter(query)
    return queryset

我的看法:

class SiteCircuitDataROView(viewsets.ReadOnlyModelViewSet):
    queryset = Circuit.objects.all()
    serializer_class = CircuitSerializer
    permission_classes = (IsAdminUser,)
    filter_class = Circuit
    filter_backends = (filters.SearchFilter,)

【问题讨论】:

  • 分享您的过滤器Circuit
  • 不要这样做:query = Q() 使用query = Circuit.objects.none(),否则不会按状态过滤。
  • 电路不是过滤器而是模型
  • 在哪个尝试动作或get_queryset?
  • @AlexW 您现在正在使用的任何一个(两者:))。

标签: django django-rest-framework django-rest-viewsets


【解决方案1】:

像下面这样改变你的观点

class SiteCircuitDataROView(viewsets.ReadOnlyModelViewSet):
    serializer_class = CircuitSerializer
    permission_classes = (IsAdminUser,)

    def get_queryset(self):
        queryset = Circuit.objects.all()
        search = self.request.GET.get('search', '').split(',')
        if search:
           query = Q()
           for term in search:
               query = query | Q(circuit__ref_no__icontains=term)
           queryset = queryset.filter(query)
        return queryset

现在,发送如下网址的请求

api/circuit/?search=AB5814765,AB827451,AB0923784

【讨论】:

  • @AlexW 请检查我的答案
  • 赋值前引用的局部变量'q'
【解决方案2】:

你可以这样做,使用__in并调用api/circuit/?refs=AB5814765|AB827451|AB0923784

class SiteCircuitDataROView(viewsets.ReadOnlyModelViewSet):
    queryset = Circuit.objects.all()
    serializer_class = CircuitSerializer
    permission_classes = (IsAdminUser,)
    filter_class = Circuit
    filter_backends = (filters.SearchFilter,)

    @action(detail=False, methods=['get'], url_path='ref_search/', permission_classes=[IsAdminUser])
    def ref_search(self, request, *args, **kwargs):
        refs = self.request.get('refs', '').split('|')
        queryset = DeviceCircuitSubnets.objects.filter(ref__in=refs)
        serializer = self.serializer_class(queryset, many=True)
        return Response(data=serializer.data)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-28
    • 2019-07-23
    • 1970-01-01
    • 2020-04-06
    • 1970-01-01
    • 2019-07-14
    • 2019-04-25
    • 2014-10-12
    相关资源
    最近更新 更多