使用ViewSet&amp ;;搜索端点Django-REST-FrameWork中的路由器

时间:2018-02-15 08:47:01

标签: python django django-rest-framework

  

Views.py

class ClientViewSet(ModelViewSet, GetOrRaiseMixin):
    serializer_class = ClientSerializer
    queryset = Client.objects.all()

    def list(self, request):
        serializer = ClientSerializer(self.queryset, many=True)
        return JsonResponse(serializer.data, status=HTTP_200_OK, safe=False)

    def retrieve(self, request, pk=None):
        client = self.get_or_raise('Client', pk)
        serializer = ClientSerializer(client)
        return JsonResponse(serializer.data, status=HTTP_200_OK)

    def create(self, request):
        serializer = ClientSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data, status=HTTP_200_OK)
        else:
            return JsonResponse({'error': 'Invalid'}, status=HTTP_400_BAD_REQUEST)

    def destroy(self, request, pk=None):
        client = self.get_or_raise('Client', pk)
        client.datetime_deleted = datetime.now()
        client.save()
        return JsonResponse(serializer.data, status=HTTP_200_OK)
  

Urls.py

router.register('clients', ClientViewSet, base_name='clients')
urlpatterns = [
    path('api/', include(router.urls)),
]
  

问题

以上版本适用于标准行为,例如create / retrieve_all / retrieve_by_id / update_by_id / delete_by_id。 但我想要的是为search_& _retrieve添加额外的enpoint。

例如:

  

/ api / clients / search /?title ='John'& age ='32'等。

所以一般来说我需要5个端点:创建/检索/更新/删除/搜索。

我可以通过“ViewSet + Routers”概念实现这一目标,还是需要做其他事情?

  

更新

我还必须删除ClientViewSet类中的“list”函数才能使此端点工作:

http://localhost:8000/api/clients/?title=John&age=32

我不知道为什么,但是当你明确定义“list”函数时,搜索端点只返回DB中的每条记录而不是过滤它,所以要注意。

2 个答案:

答案 0 :(得分:1)

而不是添加自己的搜索端点(如果您想要完全优化的搜索端点,请考虑Haystack)

您只需修改filter_class中的filter_backendssearch_fieldsModelViewSet即可为您处理并且可扩展

答案 1 :(得分:1)

您可以使用django-filter库:

from django_filters import rest_framework as filters

class ClientViewSet(ModelViewSet, GetOrRaiseMixin):
    serializer_class = ClientSerializer
    queryset = Client.objects.all()
    filter_backends = (filters.DjangoFilterBackend,)
    filter_fields = ('title', 'age')

查看此part DRF文档以了解快速入门。