【问题标题】:How to add serializers.RelatedField() to Meta class fields in django rest framework如何将 serializers.RelatedField() 添加到 django rest 框架中的 Meta 类字段
【发布时间】:2018-10-09 06:39:00
【问题描述】:

我有一个用于足球比赛的简单 API。我正在使用 Django 2.0 和 Django REST 框架。我有TeamPlayer 的这两个模型

class Team(models.Model):
    name = models.CharField(max_length=60)
    budget = models.FloatField(default=100.0) # Millions? 114.53 M

    user = models.OneToOneField(User, unique=True, on_delete=models.CASCADE)
    competitions = models.ManyToManyField(Season)

    def __str__(self):
        return self.name

class Player(models.Model):
    name = models.CharField(max_length=50)
    age = models.IntegerField(null=True)
    inMarket = models.BooleanField(default=False)
    lastInMarket = models.DateTimeField(null=True)

    team = models.ForeignKey(Team, null=True, on_delete=models.DO_NOTHING, related_name='team')

据我所知,这是定义 OneToMany 关系的正确方法,即 Team 有许多 Players。现在,另一方面,我想为具体球队显示APIView,以显示球队的所有信息,包括球员的信息。我有这两个Serializers:

class PlayersSerializer(serializers.ModelSerializer):
    team = serializers.RelatedField(read_only=True)

    class Meta:
        model = Player
        fields = ('id', 'name', 'age', 'position', 'team')

    def create(self, validated_data):
        pass

    def update(self, instance, validated_data):
        pass


class TeamSerializer(serializers.ModelSerializer):
    players = serializers.RelatedField(read_only=True, many=True)

    class Meta:
        model = Team
        fields = ('name', 'user', 'competitions')

    def create(self, validated_data):
        return Team.objects.create(**validated_data)

    def update(self, instance, validated_data):
        instance.players = validated_data
        return instance

这是迄今为止我发现的最好的检索球队球员的方法。但是,我不确定这是否是正确的方法。无论如何,我无法将players 添加到fields,因为Team 模型没有玩家属性(引发异常)。我怎么能以某种方式解决这个问题?我有点迷路了

【问题讨论】:

    标签: django django-rest-framework foreign-keys serialization


    【解决方案1】:

    这真的很容易。您可以使用您在模型中定义的related_name (team)。最好将此字段重命名为players。您可以像以前一样为 Player 定义 Serializer,然后在字段中添加 related_name。在你的情况下team(或players)。然后在 Team serializer 中为玩家添加序列化程序(如果您将他们定义为 related_name,则可以添加玩家)。

    models.py:

    class Player(models.Model):
        name = models.CharField(max_length=50)
        age = models.IntegerField(null=True)
        inMarket = models.BooleanField(default=False)
        lastInMarket = models.DateTimeField(null=True)
    
        team = models.ForeignKey(Team, null=True, on_delete=models.DO_NOTHING, related_name='players')
    

    serializers.py

    class PlayersSerializer(serializers.ModelSerializer):
        # you don't need RelatedField to Team because players will be under the team
        team = serializers.RelatedField(read_only=True)
    
        class Meta:
            model = Player
            fields = ('id', 'name', 'age', 'position', 'team')
    
        def create(self, validated_data):
            pass
    
        def update(self, instance, validated_data):
            pass
    
    class TeamSerializer(serializers.ModelSerializer):
        players = PlayerSerializer(read_only=True, many=True)
    
        class Meta:
            model = Team
            fields = ('name', 'user', 'competitions', 'players')
    
        def create(self, validated_data):
            return Team.objects.create(**validated_data)
    
        def update(self, instance, validated_data):
            instance.players = validated_data
            return instance
    

    如果您对实施有任何问题,请发送评论并告诉我它是否按预期工作。

    【讨论】:

    • 我想你在TeamSerializer中定义players时也需要source='player_set'
    • 谢谢,这对我来说很完美。正如您可能猜到的那样,我对属性related_name 感到困惑,因为它是在Player 模型中定义的
    • 很高兴为您提供帮助。我记得我用这个的时候也很困惑
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-22
    • 2015-08-26
    • 1970-01-01
    • 2016-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多