如何让ParentSerializer.children仅包含当前用户创建的ChildModel对象?
解决ParentSerializer仅显示当前用户创建的子对象的方法
方法一:自定义序列化字段实现过滤
直接在ParentSerializer里替换默认的children字段,通过自定义方法过滤当前用户的子对象,同时确保请求对象能传入序列化器上下文。
修改ParentSerializer:
class ParentSerializer(serializers.ModelSerializer): children = serializers.SerializerMethodField() class Meta: model = ParentModel fields = ('name', 'children') def get_children(self, obj): user = self.context.get('request').user # 过滤当前父对象下由当前用户创建的子模型 filtered_kids = obj.children.filter(created_by=user) return ChildSerializer(filtered_kids, many=True).data
ParentViewSet默认会把request传入序列化器上下文,若需明确确保,可添加如下代码:
class ParentViewSet(viewsets.ModelViewSet): serializer_class = ParentSerializer queryset = ParentModel.objects.all() def get_serializer_context(self): context = super().get_serializer_context() context['request'] = self.request return context
方法二:预加载过滤子对象(优化性能)
如果数据量较大,方法一可能触发N+1查询问题,可通过prefetch_related预加载过滤后的子对象,提升查询效率。
修改ParentViewSet的get_queryset方法:
from django.db.models import Prefetch class ParentViewSet(viewsets.ModelViewSet): serializer_class = ParentSerializer def get_queryset(self): user = self.request.user # 预加载并过滤当前用户的子对象,存到自定义属性中 return ParentModel.objects.prefetch_related( Prefetch( 'children', queryset=ChildModel.objects.filter(created_by=user), to_attr='filtered_children' ) )
对应修改ParentSerializer,使用预加载的过滤后数据:
class ParentSerializer(serializers.ModelSerializer): children = serializers.SerializerMethodField() class Meta: model = ParentModel fields = ('name', 'children') def get_children(self, obj): # 直接用预加载好的过滤数据 return ChildSerializer(obj.filtered_children, many=True).data
现有代码修正提示
你的ChildSerializer里Meta类写错了属性名,应该是model而非models,同时字段元组建议加逗号避免语法问题:
class ChildSerializer(serializers.ModelSerializer): class Meta: model = ChildModel fields = ('name',)
内容的提问来源于stack exchange,提问作者James Maguire
相关产品推荐
相关产品推荐

