0

I get a ValueError Cannot assign "[]": "Match.stats" must be a "Stats" instance. when I try and create a match through the browsable API but can create one through the shell just fine.

If I remove the HyperlinkedRelatedField from the MatchSerializer it can create just fine.

models.py

class Player(models.Model):
    name = models.CharField(max_length=30)
    account = models.IntegerField()
    place = models.CharField(max_length=30)
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='players')

    def __str__(self):
        return self.name


class Match(models.Model):
    game = models.IntegerField()
    length = models.IntegerField()
    win = models.BooleanField()
    player = models.ForeignKey(Player, on_delete=models.CASCADE, related_name='matches')

    def __str__(self):
        return str(self.game)



class Stats(models.Model):
    goals = models.IntegerField()
    assists = models.IntegerField()
    time = models.IntegerField()
    match = models.OneToOneField(Match, on_delete=models.CASCADE, related_name='stats')

    def __str__(self):
         return '{} {}'.format(str(self.goals), str(self.match))


class Team(models.Model):
    possession = models.IntegerField()
    goals = models.IntegerField()
    assists = models.IntegerField()
    extra = models.BooleanField(default=False)
    match = models.OneToOneField(Match, on_delete=models.CASCADE, related_name='teams')

    def __str__(self):
        return '{} - {}'.format(str(self.possession), str(self.match))

serializer.py

class UserSerializer(serializers.ModelSerializer):
    players = serializers.HyperlinkedRelatedField(many=True, view_name='players-detail', queryset=Player.objects.all())
    class Meta:
        model = User
        fields = ('id', 'username', 'email', 'first_name', 'last_name', 'players')


class PlayerSerializer(serializers.ModelSerializer):
    user = serializers.ReadOnlyField(source='user.username')
    matches = serializers.HyperlinkedRelatedField(many=True, view_name='matches-detail', queryset=Match.objects.all())
    class Meta:
        model = Player
        fields = ('id', 'name', 'account', 'place', 'user', 'matches')


class MatchSerializer(serializers.ModelSerializer):
    player = serializers.ReadOnlyField(source='player.name')
    stats = serializers.HyperlinkedRelatedField(many=True, view_name='stats-detail', queryset=Stats.objects.all())
    teams = serializers.HyperlinkedRelatedField(many=True, view_name='teams-detail', queryset=Team.objects.all())
    class Meta:
        model = Match
        fields = ('id', 'game', 'length', 'win', 'player', 'stats', 'teams')

class StatsSerializer(serializers.ModelSerializer):
    match = serializers.ReadOnlyField(source='match.game')
    class Meta:
        model = Stats
        fields = ('id', 'goals', 'assists', 'time', 'match')


class TeamSerializer(serializers.ModelSerializer):
    match = serializers.ReadOnlyField(source='match.game')
    class Meta:
        model = Team
        fields = ('id', 'possession', 'goals', 'assists', 'extra', 'match')

I can go into python manage.py shell and create a match just fine.

>>>m = Match(game=12345, length=5674, win=True, player=player1) # a previously queried player 
>>>m.save()  

I'm just a little confused what is going

1 Answer 1

1

By default, HyperlineRelatedField allow both read and write operation, so I think you need make it read-only true:

class MatchSerializer(serializers.ModelSerializer):
    player = serializers.ReadOnlyField(source='player.name')
    stats = serializers.HyperlinkedRelatedField(view_name='stats-detail', read_only=True)
    teams = serializers.HyperlinkedRelatedField(view_name='teams-detail', read_only=True)
    class Meta:
        model = Match
        fields = ('id', 'game', 'length', 'win', 'player', 'stats', 'teams')

Also, you don't need to add many=True, because both teams and stats are OneToOne relations. So one entry for both tables will be created for each match.

Sign up to request clarification or add additional context in comments.

1 Comment

I had the remove the queryset keyword argument too and ya that worked. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.