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

Django REST Framework优化JSON响应:消除外键字段重复显示

Solution to Group Messages by Conversation and Owner

Got it, let's restructure your serializers to group messages by conversation_id and owner as you requested. Here's a step-by-step implementation:

1. Create a Sub-serializer for Individual Messages

First, make a lightweight serializer to handle the unique fields per message (sender and body):

class MessageDetailSerializer(serializers.ModelSerializer):
    sender = serializers.ReadOnlyField(source='sender.id')

    class Meta:
        model = Message  # Replace with your actual Message model name
        fields = ['sender', 'body']

2. Build a Custom List Serializer for Grouping

Next, we'll override DRF's ListSerializer to group messages by their shared conversation_id and owner:

class GroupedMessageListSerializer(serializers.ListSerializer):
    def to_representation(self, data):
        # Group messages by (conversation_id, owner) pair
        message_groups = {}
        
        for message in data:
            # Use the unique pair as a key for grouping
            group_key = (message.conversation_id, message.owner)
            
            if group_key not in message_groups:
                # Initialize a new group with shared fields
                message_groups[group_key] = {
                    'conversation_id': message.conversation_id,
                    'owner': message.owner,
                    'messages': []
                }
            
            # Add the message details using our sub-serializer
            detail_serializer = MessageDetailSerializer(message, context=self.context)
            message_groups[group_key]['messages'].append(detail_serializer.data)
        
        # Convert the grouped dict back to a list for the response
        return list(message_groups.values())

Note for SerializerMethodField conversation_id:

If your conversation_id is defined via a SerializerMethodField (like your original code hints), replace message.conversation_id with a call to that method. For example:

# Inside GroupedMessageListSerializer's to_representation
# First, create an instance of your original serializer to access the method
parent_serializer = MessageSerializer(message, context=self.context)
conv_id = parent_serializer.get_conversation_id(message)
group_key = (conv_id, message.owner)
# Then use conv_id when initializing the group

3. Update Your Original Message Serializer

Modify your main MessageSerializer to use the custom list serializer, and adjust fields to only include per-message data:

class MessageSerializer(serializers.ModelSerializer):
    sender = serializers.ReadOnlyField(source='sender.id')
    # Remove conversation_id from here since it's handled in the group
    
    class Meta:
        model = Message
        fields = ['sender', 'body']
        # Tell DRF to use our grouped list serializer for bulk responses
        list_serializer_class = GroupedMessageListSerializer

    # Keep your existing get_conversation_id method if needed
    # def get_conversation_id(self, obj):
    #     return obj.conversation.id  # Example implementation

How It Works

When your DRF view returns a list of messages, the GroupedMessageListSerializer will:

  • Iterate through all message instances
  • Group them by their shared conversation_id and owner
  • Nest individual message details under a messages array for each group
  • Return the grouped structure as the results array in your response

The pagination fields (count, next, previous) will remain unchanged since DRF's pagination system uses the original queryset count.

Example Output

You'll get exactly the structure you wanted:

{
  "count": 2,
  "next": null,
  "previous": null,
  "results": [
    {
      "conversation_id": 1,
      "owner": true,
      "messages": [
        {
          "sender": 2,
          "body": "Hello There"
        },
        {
          "sender": 2,
          "body": "Second message"
        }
      ]
    }
  ]
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:11:40