Reputation: 483
Currently I have an API View that returns a dictionary that looks like this:
[
{
"id": 1,
"name": "Fly in the sky",
"thumbnail": "games/fly_in_the_sky",
"maps": [
{
"id": 1,
"name": "Blue Sea",
"thumbnail": "maps/blue_sea.jpg"
},
{
"id": 2,
"name": "Red Mountain",
"thumbnail": "maps/red_mountain.jpg"
}
],
"characters": [
{
"id": 1,
"name": "Steve",
"thumbnail": "characters/steve.jpg"
},
{
"id": 2,
"name": "Peter",
"thumbnail": "characters/peter.jpg"
}
]
}
]
I would like it to look like this instead, moving the names of all items as keys. (I would make sure ahead of time that all the names are unique so there is no key conflict)
{
"Fly in the sky": {
"id": 1,
"thumbnail": "games/fly_in_the_sky",
"maps": {
"Blue Sea": {
"id": 1,
"thumbnail": "maps/blue_sea.jpg"
},
"Red Mountain": {
"id": 2,
"thumbnail": "maps/red_mountain.jpg"
}
},
"characters": {
"Steve": {
"id": 1,
"thumbnail": "characters/steve.jpg"
},
"Peter",{
"id": 2,
"thumbnail": "characters/peter.jpg"
}
}
}
}
Is there any way of telling Django to return elements as a dictionary using a field as keys instead of an array?
My views and serializer currently look like this:
class GamesView(APIView):
def get(self, request):
game_objects = Game.objects.all()
game_serializer = GameListSerializer(game_objects, many=True)
return Response(game_serializer.data)
class MapListSerializer(ModelSerializer):
class Meta:
model = Map
fields = ('id', 'name', 'thumbnail')
class CharacterListSerializer(ModelSerializer):
class Meta:
model = Character
fields = ('id', 'name', 'thumbnail')
class GameListSerializer(ModelSerializer):
maps = MapListSerializer(many=True)
characters = CharacterListSerializer(many=True)
class Meta:
model = Game
fields = ('id', 'name', 'thumbnail', 'maps', 'characters')
Upvotes: 0
Views: 4233
Reputation: 718
Maybe this should help. But i'm not sure why you would do that. xD
class GamesView(APIView):
def get(self, request):
game_objects = Game.objects.all()
game_serializer = GameListSerializer(game_objects, many=True)
modified_response = {}
if game_serializer.data:
for game in game_serializer:
name = game.pop("name")
modified_response[name] = game
return Response(modified_response)
Upvotes: 0
Reputation: 581
When you give the parameter many=True
to serializer, it returns a list and you cannot change it. This is better because more than one object can return. I wouldn't suggest it, but if you want to return the dictionary when there is only one element, you can write a condition like below. The reason I don't recommend it that it can be difficult to parse JSON for the client.
class GamesView(APIView):
def get(self, request):
game_objects = Game.objects.all()
game_serializer = GameListSerializer(game_objects, many=True)
serializer_data = game_serializer.data
if len(serializer_data) == 1:
serializer_data = serializer_data[0]
return Response(serializer_data)
Upvotes: 1