Django嵌套序列化下如何过滤子对象WorkSpace的指定类型数据?
解决Django嵌套序列化器中关联对象的过滤问题
方案一:序列化阶段过滤关联数据
直接在Boss的序列化器中,通过SerializerMethodField过滤关联的WorkSpace,只保留指定类型的条目:
from rest_framework import serializers from .models import Boss, WorkSpace class WorkSpaceSerializer(serializers.ModelSerializer): class Meta: model = WorkSpace fields = "__all__" class BossSerializer(serializers.ModelSerializer): workspaces = serializers.SerializerMethodField() class Meta: model = Boss fields = ["id", "name", "workspaces"] # 按需调整字段 def get_workspaces(self, obj): # 若type是固定值,直接替换为'C1';动态值可从请求参数获取 target_type = self.context["request"].query_params.get("type", "C1") # 过滤当前Boss关联的指定type的WorkSpace filtered = obj.workspaces.filter(type=target_type) return WorkSpaceSerializer(filtered, many=True).data
这种方式无需额外循环处理结果,直接在序列化过程中完成过滤,逻辑直观。
方案二:查询集阶段用Prefetch优化性能
如果数据量较大,为避免N+1查询问题,可在查询Boss时就预取并过滤WorkSpace,提升整体性能:
1. 调整视图的查询集
from django.db.models import Prefetch from rest_framework.generics import ListAPIView from .models import Boss, WorkSpace from .serializers import BossSerializer class BossListView(ListAPIView): serializer_class = BossSerializer def get_queryset(self): target_type = self.request.query_params.get("type", "C1") # 定义预取规则,只获取指定type的WorkSpace prefetch_filter = Prefetch( "workspaces", queryset=WorkSpace.objects.filter(type=target_type), to_attr="filtered_workspaces" ) # 过滤关联指定type WorkSpace的Boss,同时预取过滤后的结果 return Boss.objects.filter( workspaces__type=target_type ).prefetch_related(prefetch_filter).distinct()
2. 修改序列化器使用预取数据
class BossSerializer(serializers.ModelSerializer): # 直接使用预取的过滤后数据 workspaces = WorkSpaceSerializer(many=True, source="filtered_workspaces") class Meta: model = Boss fields = ["id", "name", "workspaces"]
distinct()用于避免因WorkSpace关联导致Boss实例重复返回,to_attr指定预取结果的存储属性,序列化器直接调用即可。
内容的提问来源于stack exchange,提问作者Librain
相关产品推荐
相关产品推荐

