Как добавить serializer.RelatedField () в поля мета-классов в структуре отдыха django - PullRequest
0 голосов
/ 28 апреля 2018

У меня есть простой API для футбольной игры. Я использую Django 2.0 и Django REST Framework. У меня есть эти две модели для Team и Player

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 нет атрибута игроков (исключение повышено). Как я мог это как-то исправить? Я как бы потерялся

1 Ответ

0 голосов
/ 28 апреля 2018

Это действительно легко. Вы можете использовать related_name, который вы определили в своей модели (team). Было бы лучше переименовать это поле в players. Вы можете определить Serializer для Player, как вы сделали, а затем в поле, которое вы добавляете related_name. В вашем случае team (или players). А затем в Team serializer вы добавляете сериализатор для игроков (вы можете добавить игроков, если вы определите их как related_name).

In 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

Отправьте комментарий, если у вас возникнут проблемы с реализацией, и скажите, работает ли он так, как вы ожидаете.

...