【问题标题】:Django Filter Backend not working in restful api in djangoDjango Filter Backend 在 Django 的 restful api 中不起作用
【发布时间】:2019-06-03 00:20:25
【问题描述】:

我正在尝试使用 django-filters 在使用参数的 url 中进行搜索查询

view.py

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import SearchFilter
from .models import RecruiterRegister
from .serializers import RecruiterRegisterSerializer
# from rest_framework import filters

from rest_framework import generics

class RecruiterRegisterList(APIView):

    queryset=RecruiterRegister.objects.all()
    filter_backends = (DjangoFilterBackend,SearchFilter ,)
    filter_fields = ('email','password')
    search_fields = ('email','password')
    def get(self, request, format=None):
        recruiterRegisters = RecruiterRegister.objects.all()
        # self.filter_backends = (DjangoFilterBackend,)
        # self.filter_fields = ('password', )
        serializer = RecruiterRegisterSerializer(recruiterRegisters, many=True)
        return Response(serializer.data)


    def post(self, request, format=None):
        serializer = RecruiterRegisterSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        recruiterRegisters = self.get_object()
        recruiterRegisters.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

但我无法获得过滤后的数据。所有的api数据都出现了。

网址示例 http://127.0.0.1:8000/recruiterRegister/?password=random2

编辑了 RecruiterRegisterList 类:

class RecruiterRegisterList(generics.ListAPIView):

    queryset=RecruiterRegister.objects.all()
    serializer_class = RecruiterRegisterSerializer
    filter_backends = (DjangoFilterBackend,)
    filter_fields=('email','password')
    # search_fields = ('email','password')

    def list(self, request ):
        queryset = self.get_queryset()
        serializer = RecruiterRegisterSerializer(queryset, many=True)
        return Response(serializer.data)

【问题讨论】:

  • 为什么要按密码过滤用户?
  • 不想使用密码过滤,正在尝试任何字段@Ken4scholars
  • 就像我提到的,你不需要重写 list 方法,除非你想自定义它。 filter_queryset 方法在您没有执行的列表方法中调用。如果您真的想覆盖它,请检查原始列表方法的实现方式并使用相同的逻辑。你省略了很多东西,比如分页、过滤等。
  • 首先删除该列表方法并查看它是否有效。如果您确实需要,您可以稍后覆盖和自定义
  • 获取请求在没有列表方法的情况下工作,但过滤器不是

标签: django-rest-framework


【解决方案1】:

第一个问题是 - 为什么要通过密码进行过滤或搜索?这是一个非常不健康和不安全的设计。密码不以原始格式存储,而是经过哈希处理,因此过滤器永远不会命中

现在,即使您真的想这样做,使用 filter_backends 进行过滤也在 GenericAPIView 中实现,而在 APIView 中不可用,因此您可能希望使用来自 rest_framework.genericsListAPIview

最后,即使你使用了ListAPIView,它仍然无法工作,因为你重写了get 方法而不是调用self.filter_queryset()

使用ListAPIView 并使用已经实现的list() 方法,它将起作用

【讨论】:

    【解决方案2】:

    我只添加下面的行并且工作正常:

    filter_backends = self.filter_queryset(queryset)
    

    您的代码如下:

    class RecruiterRegisterList(generics.ListAPIView):
    
    queryset=RecruiterRegister.objects.all()
    serializer_class = RecruiterRegisterSerializer
    filter_backends = (DjangoFilterBackend,)
    filter_fields=('email','password')
    search_fields = ('email','password')
    
    def list(self, request ):
        queryset = self.get_queryset()
        filter_backends = self.filter_queryset(queryset)
        serializer = RecruiterRegisterSerializer(filter_backends, many=True)
        return Response(serializer.data)
    

    【讨论】:

      猜你喜欢
      • 2020-05-16
      • 2012-01-15
      • 1970-01-01
      • 2010-10-14
      • 2023-03-07
      • 2012-05-22
      • 1970-01-01
      • 2015-09-07
      • 2018-03-04
      相关资源
      最近更新 更多