Reputation: 11348
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
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