Django Запросы отношений Rest Framework во вложенном сериализаторе - PullRequest
1 голос
/ 17 января 2020

У меня проблемы с реализацией вложенных сериализаторов в Django REST Framework.
Я строю табло онлайн, для которого у меня сейчас три модели, и я пытаюсь сериализовать его в один ответ.

models.py

class Player(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)

    def __str__(self):
        return self.first_name


class Event(models.Model):

    user = models.ManyToManyField("Player")
    name = models.CharField(max_length=50)  
    desc = models.CharField(max_length=225)

    def __str__(self):
        return self.name

class LeadBoard(models.Model):
    """model for LeadBoard"""

    player = models.ForeignKey(Player, on_delete=models.CASCADE, related_name='leadboard_player', null=True, blank=True)
    event = models.ForeignKey(Event, on_delete=models.CASCADE, related_name='leadboard_event', null=True, blank=True)
    score = models.IntegerField()

    def __str__(self):
        return self.score

Модель события представляет собой какое-то спортивное событие, и в каждом событии может быть несколько игроков ( пользователь подал в модель события ), модель LeadBoard хранит счет игроков в каждом событии.

serializer.py

class PlayerSerializer(serializers.ModelSerializer): 

    class Meta:
        model = Player
        fields = ('id','first_name', 'last_name', 'bio')


class EventSerializer(serializers.ModelSerializer):

    user = PlayerSerializer(read_only=True, many=True)
    class Meta:
        model = Event
        fields = ('id', 'name', 'user', 'desc')


class LeadBoardSerializer(serializers.ModelSerializer):

    event = EventSerializer(read_only=True)

    class Meta:
        model = LeadBoard
        fields = ('id', 'event', 'score')

Я добавил двух игроков

         [
            {
                "id": 1,
                "first_name": "Jhon",
                "last_name": "Doe"
            },
            {
                "id": 3,
                "first_name": "Anna",
                "last_name": "Doe"
            }
        ]

и их оценки в модели LeadBoard

[
    {
        "id": 1,
        "player": 1,
        "event": 1,
        "score": 20
    },
    {
        "id": 2,
        "player": 3,
        "event": 1,
        "score": 90
    }
]

Это ответ LeadBoard,

[
    {
        "id": 1,
        "event": {
            "id": 1,
            "name": "event2020",
            "user": [
                {
                    "id": 1,
                    "first_name": "Jhon",
                    "last_name": "Doe"
                },
                {
                    "id": 3,
                    "first_name": "Anna",
                    "last_name": "Doe"
                }
            ],
            "desc": "event description"
        },
        "score": 20
    },
    {
        "id": 2,
        "event": {
            "id": 1,
            "name": "event2020",
            "user": [
                {
                    "id": 1,
                    "first_name": "Jhon",
                    "last_name": "Doe"
                },
                {
                    "id": 3,
                    "first_name": "Anna",
                    "last_name": "Doe"
                }
            ],
            "desc": "event description"
        },
        "score": 90
    }
]

Но я ожидаю получить ответ, подобный этому, который возвращает игроков (пользователей) событий и их оценки правильно.

[
    {
        "id": 1,
        "event": {
            "id": 1,
            "name": "event2020",
            "user": [
                {
                    "id": 1,
                    "first_name": "Jhon",
                    "last_name": "Doe",
                    "score": 20
                },
                {
                    "id": 3,
                    "first_name": "Anna",
                    "last_name": "Doe",
                    "score": 90
                }
            ],
            "desc": "event description"
        }
    }
]

Что мне здесь не хватает?
Я новичок в Django и Django Rest Framework.
Я ценю любую помощь в этом, спасибо заранее!

1 Ответ

1 голос
/ 17 января 2020

Вы должны отвечать по событию, а не по списку лидеров.

class PlayerSerializer(serializers.ModelSerializer): 

   class Meta:
        model = Player
        fields = ('id','first_name', 'last_name', 'bio')

class LeadBoardSerializer(serializers.ModelSerializer):

    player = PlayerSerializer(read_only=True)

    class Meta:
        model = LeadBoard
        fields = ('id', 'player', 'score')

class EventSerializer(serializers.ModelSerializer):

    leadboard_event = LeadBoardSerializer(read_only=True, many=True)

    class Meta:
        model = Event
        fields = ('id', 'name', 'desc', 'leadboard_event')

теперь используйте представление для получения списка событий

Обновите 1 , если хотите получить счет в игроке.

class PlayerSerializer(serializers.Serializer):  
    player_id = serializers.IntegerField()
    first_name = serializers.CharField(max_length=256)
    last_name = serializers.CharField(max_length=256)
    score = serializers.IntegerField()

class LeadBoardSerializer(serializers.ModelSerializer):

    player = serializers.SerializerMethodField()

    class Meta:
        model = LeadBoard
        fields = ('id', 'player')

    def get_player(self,obj):
        player_dict = {'player_id': obj.player.id, 'first_name': obj.player.first_name, 'last_name': obj.player.last_name, 'score': obj.score}
        result = PlayerSerializer(data=player_dict)
        return result

class EventSerializer(serializers.ModelSerializer):

    leadboard_event = LeadBoardSerializer(read_only=True, many=True)

    class Meta:
        model = Event
        fields = ('id', 'name', 'desc', 'leadboard_event')

Попробуйте.

...