You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中过滤嵌套关联对象:使模块接口仅返回未删除的关联房间

Fixing Module GET Request to Return Only Non-Deleted Rooms

I see the issue here—your current filter correctly fetches Modules that are not deleted and have at least one non-deleted Room, but it doesn't filter the Rooms attached to each Module in the final response. The rooms field in your serializer is still pulling all related Rooms for a Module, regardless of their is_deleted status. Let's fix this with two reliable approaches:

Approach 1: Use a SerializerMethodField to Filter Rooms Directly in the Serializer

This is a straightforward way to control which Rooms get serialized. We'll replace the direct RoomSerializer reference with a SerializerMethodField that explicitly returns only non-deleted Rooms:

class ModuleSerializer(serializers.ModelSerializer):
    rooms = serializers.SerializerMethodField()

    def get_rooms(self, obj):
        # Filter the rooms queryset to only include non-deleted entries
        non_deleted_rooms = obj.rooms.filter(is_deleted=False)
        return RoomSerializer(non_deleted_rooms, many=True).data

    class Meta:
        model = Module
        fields = "__all__"

You can simplify your view's queryset to just fetch non-deleted Modules (since room filtering is now handled in the serializer):

class add_module(APIView):
    def get(self, request, format=None):
        module = Module.objects.filter(is_deleted=False)
        module_serializer = ModuleSerializer(module, many=True)
        return Response(module_serializer.data, status=status.HTTP_200_OK)

Approach 2: Use Prefetch to Efficiently Load Filtered Rooms (Better for Performance)

If you want to avoid extra database queries (preventing N+1 query issues), use Django's Prefetch object to preload only non-deleted Rooms along with your Modules:

First, update your view's queryset to use Prefetch:

from django.db.models import Prefetch

class add_module(APIView):
    def get(self, request, format=None):
        # Prefetch only non-deleted rooms for each module
        prefetch_rooms = Prefetch(
            'rooms',
            queryset=Room.objects.filter(is_deleted=False),
            to_attr='non_deleted_rooms'
        )
        module = Module.objects.filter(is_deleted=False).prefetch_related(prefetch_rooms)
        module_serializer = ModuleSerializer(module, many=True)
        return Response(module_serializer.data, status=status.HTTP_200_OK)

Then adjust your serializer to use the preloaded non_deleted_rooms attribute:

class ModuleSerializer(serializers.ModelSerializer):
    rooms = RoomSerializer(source='non_deleted_rooms', read_only=True, many=True)

    class Meta:
        model = Module
        fields = "__all__"

Why Your Original Code Didn't Work

Your original filter Module.objects.filter(is_deleted=False, rooms__is_deleted=False) acts as a Module-level filter—it only returns Modules that have at least one non-deleted Room. But it doesn't modify the rooms queryset fetched for each Module, so all related Rooms (including deleted ones) are still passed to the serializer.

Either approach above will ensure only non-deleted Rooms are included in each Module's response.

内容的提问来源于stack exchange,提问作者somya goyal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 14:32:33