Frantz Paul
Frantz Paul

Reputation: 167

Django Rest Framework nested serializer object is null

I have a two model setup using the Django Rest Framework. One model is a nested serializer into another object. One model is Player and the other model is TeamData. I want TeamData to be nested into Player.

# models.py
from django.db import models


class TeamData(models.Model):
    urlName = models.CharField(max_length=50)
    city = models.CharField(max_length=50)
    nickname = models.CharField(max_length=50)
    tricode = models.CharField(max_length=3)

    def __str__(self):
        return self.city


class Player(models.Model):
    firstName = models.CharField(max_length=100)
    lastName = models.CharField(max_length=100)
    jersey = models.CharField(max_length=10)
    pos = models.CharField(max_length=10)
    posExpanded = models.CharField(max_length=10)
    heightFeet = models.CharField(max_length=2)
    heightInches = models.CharField(max_length=2)
    weightPounds = models.CharField(max_length=5)
    personId = models.CharField(max_length=50)
    teamData = models.ForeignKey(
        TeamData, on_delete=models.CASCADE,  null=True, blank=True)
    isAllStar = models.BooleanField()
    orderChar = models.CharField(max_length=1)
    playerUrl = models.CharField(max_length=50)
    displayName = models.CharField(max_length=100)



#serializer.py
from rest_framework import serializers
from .models import *


class TeamDataSerializer(serializers.ModelSerializer):
    class Meta:
        model = TeamData
        fields = ('id', 'urlName', 'city', 'nickname', 'tricode')


class PlayerSerializer(serializers.ModelSerializer):

    teamData = TeamDataSerializer('teamData')

    class Meta:
        model = Player
        fields = ('id', 'firstName', 'lastName', 'jersey', 'pos',
                  'posExpanded', 'heightInches', 'weightPounds', 'personId',
                  'teamData', 'isAllStar', 'orderChar', 'playerUrl', 'displayName')

    def create(self, validated_data):
        teamData = validated_data.pop('teamData')
        player = Player.objects.create(**validated_data)
        return player


#views.py
from rest_framework import viewsets
from .models import Player, TeamData
from rest_framework import viewsets, permissions
from .serializers import *
class PlayerViewSet(viewsets.ModelViewSet):
    queryset = Player.objects.all()
    permission_classes = [
        permissions.AllowAny
    ]
    serializer_class = PlayerSerializer

when I do a POST request of

{
        "firstName": "Ste",
        "lastName": "Adams",
        "jersey": "12",
        "pos": "C",
        "posExpanded": "Center",
        "heightFeet": "6",
        "heightInches": "11",
        "weightPounds": "265",
        "personId": "203500",
        "teamData": {
            "id": "1",
            "urlName": "thunder",
            "city": "Oklahoma City",
            "nickname": "Thunder",
            "tricode": "OKC"
        },
        "isAllStar": false,
        "orderChar": "A",
        "playerUrl": "/players/steven/adams/203500",
        "displayName": "Adams, Steven"
    }

I get back

{
    "id": 6,
    "firstName": "Ste",
    "lastName": "Adams",
    "jersey": "12",
    "pos": "C",
    "posExpanded": "Center",
    "heightInches": "11",
    "weightPounds": "265",
    "personId": "203500",
    "teamData": null,
    "isAllStar": false,
    "orderChar": "A",
    "playerUrl": "/players/steven/adams/203500",
    "displayName": "Adams, Steven"
}

Any idea why teamData is null? I suspect it may have something to do with the view but I'm not sure what the problem is.

Upvotes: 2

Views: 1445

Answers (1)

JPG
JPG

Reputation: 88659

You are passing a string to PlayerSerializer for no reason. It should be,

class PlayerSerializer(serializers.ModelSerializer):
    teamData = TeamDataSerializer() # without passing anything to the serializer

    # other code

also, you are not creating TeamData instance in your create() method of the serializer.


#final code sample
class PlayerSerializer(serializers.ModelSerializer):
    teamData = TeamDataSerializer()

    class Meta:
        model = Player
        fields = ('id', 'firstName', 'lastName', 'jersey', 'pos',
                  'posExpanded', 'heightInches', 'weightPounds', 'personId',
                  'teamData', 'isAllStar', 'orderChar', 'playerUrl', 'displayName')

    def create(self, validated_data):
        validated_data['teamData'] = TeamData.objects.create(**validated_data.get('teamData', {}))
        player = Player.objects.create(**validated_data)
        return player

Upvotes: 2

Related Questions