Sethen
Sethen

Reputation: 11348

Django rest framework add data to serializer

I am trying to add data to my serializer. What I have is a Game model and a Game can have multiple Match models attached to it. The thing is, the Game model doesn't know about this relationship. The relationship is on the Match model as a foreign key to the Game.

However, there are times when I am getting a Game I want to include the Match models with them. Here is my model for a Game:

import uuid
from django.db import models
from django.utils import timezone

class Game(models.Model):
    created_at = models.DateTimeField(editable=False)
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    updated_at = models.DateTimeField(editable=False)

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        ''' On save, update timestamps '''
        if not self.created_at:
            self.created_at = timezone.now()
        self.updated_at = timezone.now()
        return super(Analysis, self).save(*args, **kwargs)

    class Meta:
        db_table = "games"

And my Match model:

import uuid
from django.db import models
from django.utils import timezone
from games.models import Game

class Match(models.Model):
    game = models.ForeignKey(Game, on_delete=models.CASCADE)
    created_at = models.DateTimeField(editable=False)
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    updated_at = models.DateTimeField(editable=False)

    def save(self, *args, **kwargs):
        ''' On save, update timestamps '''
        if not self.created_at:
            self.created_at = timezone.now()
        self.updated_at = timezone.now()
        return super(Match, self).save(*args, **kwargs)

    class Meta:
        db_table = "matches"

And my GameSerializer:

from rest_framework import serializers
from games.models import Game
from games.serializers import GameSerializer

class GameSerializer(serializers.ModelSerializer):
    class Meta:
        model = Game
        fields = ('id', 'created_at', 'updated_at')

I am assuming that I need to tweak my GameSerializer to make this work correctly and send down the related data. How do I do this?

Upvotes: 1

Views: 2451

Answers (1)

Aswin Murugesh
Aswin Murugesh

Reputation: 11080

You need to add the match field to your GameSerializer, and handle the save yourself.

class GameSerializer(serializers.ModelSerializer):
    matches = MatchSerializer(many=True, source='match_set')

    def save(self):
        matches = self.validated_data.get('matches', [])
        game = super(GameSerializer, self).save()
        for match in matches:
            match['game'] = game
            Match.objects.create(**match)

Add matches to your fields. In the validated_data of the serializer, matches will be a list of validated datas from MatchSerializer. So you can go ahead and create the Match object directly in your GameSerializer save.

Ref: http://www.django-rest-framework.org/api-guide/relations/#writable-nested-serializers

Or if your usecase involves matches sending already existing Match object and you will only need to send the ids in your data, then use this:

class GameSerializer(serializers.ModelSerializer):
    matches = serializers.ListField(
        child=serializers.PrimaryKeyRelatedField(Match))

    def save(self):
        matches = self.validated_data.get('matches')
        game = super(GameSerializer, self).save()
        for match in matches:
            match.game = game
            match.save()

Upvotes: 2

Related Questions