Django REST:传递连接模型中的额外字段

时间:2018-02-01 10:17:23

标签: python django django-rest-framework

我需要在json响应中添加不属于我的模型的其他字段。这可能吗?模型使用多个表连接,但没有直接连接。

models.py

class Message(models.Model):
    body = models.TextField(max_length=500, blank=False)
    sender = models.ForeignKey(User)
    timestamp = models.DateTimeField(auto_now_add=True)
    conversation = models.ForeignKey(Conversation)

serializers.py

class MessageSerializer(serializers.ModelSerializer):
    conversation = serializers.ReadOnlyField(source='conversation.id')
    sender = serializers.ReadOnlyField(source='sender.id')
    # task = TaskSerializer(source='conversation__task_worker__task.id')
    # This commented code above is not working, but this is what I need.
    class Meta:
        model = Message
        fields = '__all__'

所以我需要的是传递task的值,这可以通过返回几个表来找到。例如。如果当前模型是Message,我需要: 消息 - >会话 - > Task_worker - >任务(得到这个)

我当前的json回复是:

{
    "count": 2,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": 1,
            "conversation": 1,
            "sender": 2,
            "body": "Hello There",
            "timestamp": "2018-01-31T17:48:19.680113Z"
        },
        {
            "id": 3,
            "conversation": 1,
            "sender": 2,
            "body": "Can you do the task",
            "timestamp": "2018-02-01T09:39:24.797218Z"
        }
    ]
}

理想情况下 ,我想要以下回复:

{
    "count": 2,
    "next": null,
    "previous": null,
    "conversation": 1,
    "task": 5,
    "any_extra_fields_key": 'value',
    "results": [
        {
            "id": 1,
            "sender": 2,
            "body": "Hello There",
            "timestamp": "2018-01-31T17:48:19.680113Z"
        },
    ]
}

响应在(列表视图)之后:GET /api/conversations/<conversation-id>/messages/

编辑:添加了views.py

class MessageList(generics.ListCreateAPIView):
    serializer_class = MessageSerializer

    def get_queryset(self):
        conversation = Conversation.objects.get(pk=self.kwargs['conv_id'])
        queryset = Message.objects.filter(conversation=conversation)
        return queryset

    def perform_create(self, serializer):
        conversation = Conversation.objects.get(pk=self.kwargs['conv_id'])
        serializer.save(sender=self.request.user, conversation=conversation)

编辑2:

class MessageSerializer(serializers.ModelSerializer):
    sender = serializers.ReadOnlyField(source='sender.id')
    children_list = serializers.SerializerMethodField('get_children')

    def get_children(self, obj):
        serializer = TaskSerializer(source='conversation__task_worker__task', many=True)
        return serializer.data

    class Meta:
        model = Message
        fields = ['children_list','sender','conversation','timestamp']

输出:

{
    "count": 2,
    "next": null,
    "previous": null,
    "results": [
        {
            "children_list": [],
            "sender": 2,
            "conversation": 1,
            "timestamp": "2018-01-31T17:48:19.680113Z"
        },
        {
            "children_list": [],
            "sender": 2,
            "conversation": 1,
            "timestamp": "2018-02-01T09:39:24.797218Z"
        }
    ]
}

首先,子列表是空的,但它应该是任务,并且它仍然在'results'键内,因为children_list是同一个任务,所以会产生大量重复。

1 个答案:

答案 0 :(得分:0)

我需要

SerializerMethodField来获取我想要的数据。但是,结构仍然是一个问题

class MessageSerializer(serializers.ModelSerializer):
sender = serializers.ReadOnlyField(source='sender.id')
task_id = serializers.SerializerMethodField()

def get_task_id(self, obj):
    task = Task.objects.filter(task_worker__conversation__message=obj)[0]
    return task.id


class Meta:
    model = Message
    fields = ['task_id','sender','conversation','timestamp']