如何使用ModelSerializer添加其他顶级JSON字段

时间:2018-02-21 19:50:28

标签: django django-rest-framework

我正在使用ModelSerializer中的Django Rest Framework来创建API。 ModelSerializer非常适合返回我查询数据库的JSON列表。但我需要在JSON响应的根级别有一些额外的字段。如何将查询结果提升到另一个级别,并在JSON对象的根目录中添加自定义字段?

这是API查询返回的内容:

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "user": {
            "username": "myuser"
        },
        "content": "Another tweet",
        "timesince": "2 weeks, 3 days",
        "url": "/tweet/3/",
        "id": 3
    },
    {
        "user": {
            "username": "myuser"
        },
        "content": "a tweet",
        "timesince": "2 weeks, 3 days",
        "url": "/tweet/2/",
        "id": 2
    }
]

这就是我想要的:

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "custom_field": "custom value",
    "result": [
            {
                "user": {
                    "username": "myuser"
                },
                "content": "Another tweet",
                "timesince": "2 weeks, 3 days",
                "url": "/tweet/3/",
                "id": 3
            },
            {
                "user": {
                    "username": "myuser"
                },
                "content": "a tweet",
                "timesince": "2 weeks, 3 days",
                "url": "/tweet/2/",
                "id": 2
            }
    ]
}

serializer.py:

from django.utils.timesince import timesince

from rest_framework import serializers

from tweets.models import Tweet
from accounts.api.serializers import UserDisplaySerializer

class TweetSerializer(serializers.ModelSerializer):
    user = UserDisplaySerializer(read_only=True)
    timesince = serializers.SerializerMethodField()
    url = serializers.CharField(source='get_absolute_url', read_only=True)

    class Meta:
        model = Tweet
        fields = [
            'user',
            'content',
            'timesince',
            'url',
            'id',
            ]

    def get_timesince(self, obj):
        return timesince(obj.created)

views.py:

from django.db.models import Q
from rest_framework import generics
from rest_framework import exceptions
from rest_framework import permissions

from tweets.models import Tweet
from tweets.api import serializers

class TweetListAPIView(generics.ListAPIView):
    serializer_class = serializers.TweetSerializer

    def get_queryset(self, *args, **kwargs):
        queryset = Tweet.objects.all()
        queryset = queryset.order_by('-id')

        return queryset

1 个答案:

答案 0 :(得分:2)

您可以通过覆盖list的{​​{1}}方法,然后将此新字段添加到响应中来执行此操作:

ListAPIView