Django Rest Framework中能否在函数内创建过滤器而非类?
问题解答
可以在DRF视图函数中直接实现筛选逻辑,无需单独定义FilterSet类,下面提供两种可行方案:
方案1:手动从请求参数获取值并过滤
直接在get方法中提取请求参数,对QuerySet进行过滤,逻辑简单直观,无需依赖django-filter库:
class AccountList(APIView): """ List all accounts, or create a new account.... """ def get(self, request, format=None): # 初始化基础查询集 accounts = Account.objects.all() # 获取请求中的筛选参数 document = request.query_params.get('document') document_type = request.query_params.get('document_type') # 根据参数执行过滤 if document: accounts = accounts.filter(document__exact=document) if document_type: accounts = accounts.filter(document_type__exact=document_type) # 序列化并返回结果 serializer = AccountSerializer(accounts, many=True) return Response({'data':serializer.data}, status=status.HTTP_200_OK) # post方法保持原有实现不变 def post(self, request, format=None): serializer = AccountSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response({'Message':'Registro creado exitosamente'}, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
方案2:动态创建FilterSet类(适用于偏好django-filter语法的场景)
如果习惯使用django-filter的语法,也可以在视图函数内部动态生成FilterSet类,不过相比手动过滤略显冗余:
from django_filters.rest_framework import FilterSet class AccountList(APIView): """ List all accounts, or create a new account.... """ def get(self, request, format=None): # 动态生成FilterSet类 DynamicAccountFilter = type('DynamicAccountFilter', (FilterSet,), { 'Meta': type('Meta', (), { 'model': Account, 'fields': { 'document': ['exact'], 'document_type': ['exact'] } }) }) # 应用过滤器 accounts = Account.objects.all() filter_set = DynamicAccountFilter(request.query_params, queryset=accounts) filtered_accounts = filter_set.qs # 序列化并返回结果 serializer = AccountSerializer(filtered_accounts, many=True) return Response({'data':serializer.data}, status=status.HTTP_200_OK) # post方法保持原有实现不变 def post(self, request, format=None): serializer = AccountSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response({'Message':'Registro creado exitosamente'}, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
额外提示
你原有视图代码中定义的filter_class和filter_backends属性是无效的——APIView不会自动识别这些配置,只有继承GenericAPIView的视图才会处理这类属性。如果想继续使用已定义的AccountFilter,可以手动实例化并应用:
def get(self, request, format=None): accounts = Account.objects.all() filter_set = AccountFilter(request.query_params, queryset=accounts) filtered_accounts = filter_set.qs serializer = AccountSerializer(filtered_accounts, many=True) return Response({'data':serializer.data}, status=status.HTTP_200_OK)
内容的提问来源于stack exchange,提问作者Diego Castañeda
相关产品推荐
相关产品推荐

