如何在Django中过滤嵌套关联对象:使模块接口仅返回未删除的关联房间
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

