Django REST Framework实现Bulk GET批量查询TaxonData实例问题
报错原因及修复
你遇到的AttributeError: type object 'taxonDataListViewSet' has no attribute 'get_extra_actions'报错核心原因是视图类的继承体系和注册方式不匹配:
- 你定义的
taxonDataListViewSet继承的是generics.ListAPIView,属于DRF普通类视图,不具备ViewSet的特有方法 - 如果你在
urls.py中用DRF的DefaultRouter/SimpleRouter注册了这个类,router默认要求视图必须是ViewSet子类,会自动调用get_extra_actions方法,普通类视图没有这个方法就会报错
修复方案二选一:
- 改为普通URL注册(不使用router),在
urls.py中直接绑定视图:
from django.urls import path from .views import taxonDataListViewSet urlpatterns = [ path('taxon-data/', taxonDataListViewSet.as_view(), name='taxon-data-list'), ]
- 修改视图继承体系为ViewSet,适配router注册:
from rest_framework import viewsets class taxonDataListViewSet(viewsets.ReadOnlyModelViewSet): serializer_class = taxonDataSerializer queryset = TaxonData.objects.all()
批量查询功能实现
完全可以实现单次请求传入多组条件返回匹配结果,全程仅执行1次数据库查询,性能远高于循环单条请求。最优实现不需要额外引入第三方组件,用Django原生Q对象拼接查询条件即可,具体实现如下:
实现思路
- 用POST请求承载批量查询参数(GET请求不适合传递复杂列表结构)
- 先校验传入的参数列表格式合规性
- 把每组查询条件封装为Q对象,用OR逻辑拼接所有条件,一次性查询数据库
- 序列化查询结果返回即可
完整代码
1. 新增参数校验序列化器(serializers.py)
from rest_framework import serializers from .models import TaxonData # 用来校验传入的查询条件格式 class TaxonQuerySerializer(serializers.Serializer): kingdom = serializers.CharField(max_length=64, allow_null=True, required=False) phylum = serializers.CharField(max_length=64, allow_null=True, required=False) class_taxonomic = serializers.CharField(max_length=64, allow_null=True, required=False) order = serializers.CharField(max_length=64, allow_null=True, required=False) family = serializers.CharField(max_length=64, allow_null=True, required=False) genus = serializers.CharField(max_length=64, allow_null=True, required=False) species = serializers.CharField(max_length=64, allow_null=True, required=False) taxon_rank = serializers.CharField(max_length=64, required=True) # 原有结果序列化器保持不变,建议按Python规范改为大驼峰命名 class TaxonDataSerializer(serializers.ModelSerializer): class Meta: model = TaxonData fields = '__all__'
2. 重写视图逻辑(views.py)
from rest_framework import generics from rest_framework.response import Response from django.db.models import Q from .models import TaxonData from .serializers import TaxonDataSerializer, TaxonQuerySerializer class TaxonDataBatchQueryView(generics.GenericAPIView): serializer_class = TaxonDataSerializer def post(self, request, *args, **kwargs): # 校验传入的批量查询参数 query_serializer = TaxonQuerySerializer(data=request.data, many=True) query_serializer.is_valid(raise_exception=True) query_list = query_serializer.validated_data # 拼接OR逻辑的查询条件 query_filter = Q() for condition in query_list: query_filter |= Q(**condition) # 一次性查询所有匹配结果,仅执行1次SQL result_set = TaxonData.objects.filter(query_filter) # 序列化返回结果 return Response(self.get_serializer(result_set, many=True).data)
3. URL配置(urls.py)
from django.urls import path from .views import TaxonDataBatchQueryView urlpatterns = [ path('taxon-data/batch-query/', TaxonDataBatchQueryView.as_view(), name='taxon-batch-query'), ]
调用方式
POST请求到上述接口,请求体直接传入你给出的JSON格式参数列表即可,接口会返回所有匹配的TaxonData模型实例。
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

