Skip to main content
 首页 » 编程设计

python之尝试通过 Django REST Framework 创建时出现 ValueError

2024年11月24日31yjmyzz

我得到一个 ValueError Cannot assign "[]": "Match.stats"must be a "Stats"instance。当我尝试通过可浏览的 API 创建匹配项但可以通过 shell 创建匹配项时。

如果我从 MatchSerializer 中删除 HyperlinkedRelatedField,它就可以正常创建。

模型.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)) 

序列化器.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') 

我可以进入 python manage.py shell 并创建一个匹配项。

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

我只是有点困惑,这是怎么回事

请您参考如下方法:

默认情况下,HyperlineRelatedField允许读写操作,所以我认为你需要把它设为只读:

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') 

此外,您不需要添加many=True,因为teams 和stats 都是OneToOne 关系。因此,将为每个匹配项创建两个表的一个条目。