Phil Dwan
Phil Dwan

Reputation: 91

DRF one to many serialization -- AttributeError from missing field

Error:

AttributeError at /stats/matches

Got AttributeError when attempting to get a value for field players on serializer MatchSerializer. The serializer field might be named incorrectly and not match any attribute or key on the Match instance. Original exception text was: 'Match' object has no attribute 'players'.


Models:

Every Match has 10 players.

class Match(models.Model):
    tournament = models.ForeignKey(Tournament, blank=True)
    mid = models.CharField(primary_key=True, max_length=255)
    mlength = models.CharField(max_length=255)
    win_rad = models.BooleanField(default=True)

class Player(models.Model):
    match = models.ForeignKey(Match, on_delete=models.CASCADE)
    playerid = models.CharField(max_length=255, default='novalue')
    # There is also a Meta class that defines unique_together but its omitted for clarity.

Serializers:

class PlayerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Player
        fields = "__all__"

class MatchSerializer(serializers.ModelSerializer):
    players = PlayerSerializer(many=True)
    class Meta:
        model = Match
        fields = ("mid","players")

Upvotes: 1

Views: 761

Answers (2)

JPG
JPG

Reputation: 88559

The problem here is that Match model has not an attribute called players, remember that you are trying to get backwards relationship objects, so you need to use players_set as field as django docs says.

You could solve this in Two Ways
1. Adding a source parameter to the PlayerSerializer

class MatchSerializer(serializers.ModelSerializer):
    players = PlayerSerializer(many=True, source='player_set')
    class Meta:
        model = Match
        fields = ("mid", "players")

2. Change the lookup-field

class MatchSerializer(serializers.ModelSerializer):
    player_set = PlayerSerializer(many=True)
    class Meta:
        model = Match
        fields = ("mid","player_set")

Upvotes: 4

mrehan
mrehan

Reputation: 1182

The MatchSerializer search for a players attribute in Match's instance, but it couldn't find and you get the following error:

AttributeError at /stats/matches

Got AttributeError when attempting to get a value for field players on 
serializer MatchSerializer. The serializer field might be named 
incorrectly and not match any attribute or key on the Match instance. 
Original exception text was: 'Match' object has no attribute 'players'.

In DRF serializer, a parameter called source will tell explicitly where to look for the data. So, change your MatchSerializer as follow:

class MatchSerializer(serializers.ModelSerializer):
    players = PlayerSerializer(many=True, source='player_set')
    class Meta:
        model = Match
        fields = ("mid", "players")

Hope it helps.

Upvotes: 5

Related Questions