I am using the ModelSerializer from the Django Rest Framework to create an API. The ModelSerializer works great for returning JSON lists of whatever I query the database for. But I need to have some additional fields at the root level of the JSON response. How can I bump the query result to another level and add custom fields at the root of the JSON object?
This is what the API query returns:
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
}
]
This is what I want:
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