Django Rest обратные вложенные отношения в сериализаторах

Я работаю над созданием конечной точки только GET, которая показывает турнирную таблицу данного сезона для спортивной лиги. Честно говоря, на данный момент я перепробовал почти все, но безуспешно. Все другие сериализаторы пока работают нормально, и нет никаких проблем с тем, как настроена моя база данных. Я опустил многие поля и таблицы из-за сложности, но все, что имеет отношение к вопросу, включено ниже.

Сначала позвольте мне показать вам примерный формат того, как я хочу вернуть JSON.

Образец ответа (Конечная цель)

      {
        divisions: [
          {
            "divisionName": "WEEKNIGHT B",
            "divisionId": "ee68d8ab-2752-4df6-b11d-d289573c66df",
            teams: [
              {
                "teamId": "b07560bc-aac2-4c6c-bbfe-11a368137712",
                "statsId": "53852698-9b78-4f36-9a2e-4751b21972f9",
                "teamName": "FNA",
              },
              {
                "teamId": "406eb5aa-6004-4220-b219-59476a3136d1",
                "statsId": "a96ebf10-87c5-4f19-99c3-867253f4a502",
                "teamName": "COPENHAGEN ROAD SODAS",
              },
            ]
          },
          {
            "divisionName": "WEEKNIGHT C",
            "divisionId": "4e1469ae-2435-4a3d-a621-19a979ede7c1",
            teams: [
              {
                "teamId": "ebc7e632-073e-4484-85f9-29c0997bec25",
                "statsId": "cd6373a7-4f53-4286-80f2-eb3a8a49ee3a",
                "teamName": "HAWKS",
                "gamesPlayed": 29,
              },
              {
                "teamId": "d8cda7a6-15f4-4e8f-8c65-ef14485957e4",
                "statsId": "4492a128-763a-44ad-9ffa-abae2c39b425",
                "teamName": "DUISLANDERS",
              },
            ]
          }
        ]
      }

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

Пример запроса, чтобы показать, как это можно сделать с помощью запросов

    standingsDict = {
        "standings": []
    }
    divisionList = []
    season = Season.objects.get(name='Fall 2021')
    divisions = Division.objects.filter(seasondivision__season__id=season.id)
    for div in divisions:
        teamstats = TeamStats.objects.filter(
            season_division_team__season_division__season_id=season.id,
            season_division_team__season_division__division_id=div)
        divDict = {
            "divisionName": div.name,
            "divisionId": div.id,
            "teams": []
        }
        teamsList = []
        for stats in teamstats:
            teamDict = {
                "teamId": stats.season_division_team.team.id,
                "statsId": stats.id,
                "seasonDivisionTeamId": stats.season_division_team_id,
                "teamName": stats.season_division_team.team.name,
            }
            teamsList.append(teamDict)
        divDict['teams'] = teamsList
        divisionList.append(divDict)
    standingsDict['standings'] = divisionList

Выходной фрагмент этого цикла

{
   "standings":[
      {
         "divisionName":"WEEKNIGHT B",
         "divisionId":"UUID(""ee68d8ab-2752-4df6-b11d-d289573c66df"")",
         "teams":[
            {
               "teamId":"UUID(""756ea44f-885f-4ea0-ae4c-8a72c894067f"")",
               "statsId":"UUID(""8ef1f683-ad5b-40d8-9277-0c2689cff771"")",
               "seasonDivisionTeamId":"UUID(""19e29f9a-af04-4a4f-9e38-bad0cbf8817d"")",
               "teamName":"GABAGOOLS"
            },
            {
               "teamId":"UUID(""aefdc0dc-e2aa-4ce5-ad28-47f0724b57ab"")",
               "statsId":"UUID(""05e0012c-0adc-4d15-bbc5-901e49489667"")",
               "seasonDivisionTeamId":"UUID(""8adab3d1-7614-4ece-92f5-f0ab34b23c4c"")",
               "teamName":"LONG BEACH THUNDER MAJOR"
            },

В настоящее время с тем, как все настроено, я могу перейти к отношениям FK, чтобы получить их прямым способом, например, я могу перейти от SeasonDivisionTeam, получить TeamStatsSerializer, и для каждой команды я могу отобразить дивизион. Но это отображает один и тот же дивизион несколько раз для всех командных статистик, что не то, что я ищу.

Модели

class BaseModel(LifecycleModelMixin, models.Model):
    date_modified = models.DateTimeField(auto_now=True)
    date_created = models.DateTimeField(auto_now_add=True)
    id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)

    class Meta:
        abstract = True


class Season(BaseModel):
    name = models.CharField(max_length=50)
    startDate = models.DateField(null=True, blank=True)
    endDate = models.DateField(null=True, blank=True)


class Division(BaseModel):
    name = models.CharField(max_length=50)
    seasons = models.ManyToManyField(Season, through='SeasonDivision')


class SeasonDivision(LifecycleModelMixin, models.Model):
    id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
    division = models.ForeignKey(Division, on_delete=models.CASCADE)
    season = models.ForeignKey(Season, on_delete=models.CASCADE)


class Team(BaseModel):
    name = models.CharField(max_length=50)
    season_divisions = models.ManyToManyField(SeasonDivision, through='SeasonDivisionTeam')


class SeasonDivisionTeam(LifecycleModelMixin, models.Model):
    id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
    team = models.ForeignKey(Team, on_delete=models.CASCADE)
    season_division = models.ForeignKey(SeasonDivision, on_delete=models.CASCADE)


class Player(BaseModel):
    season_division_teams = models.ManyToManyField(SeasonDivisionTeam, through='SeasonDivisionTeamPlayer')
    firstName = models.CharField(max_length=80)


class SeasonDivisionTeamPlayer(LifecycleModelMixin, models.Model):
    id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
    player = models.ForeignKey(Player, on_delete=models.CASCADE)
    season_division_team = models.ForeignKey(SeasonDivisionTeam, on_delete=models.CASCADE)


class PlayerStats(BaseModel):
    season_division_team_player = models.ForeignKey(SeasonDivisionTeamPlayer, on_delete=models.CASCADE)
    goals = models.IntegerField(default=0)


class TeamStats(BaseModel):
    season_division_team = models.ForeignKey(SeasonDivisionTeam, on_delete=models.CASCADE)
    regWins = models.IntegerField(default=0)

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

class StandingsSerializer(serializers.ModelSerializer):
    teamstats = TeamStatsSerializer(many=True, source='teamstats_set')

    class Meta:
        model = SeasonDivisionTeam
        fields = [
            "teamstats",
        ]
        depth = 1

Просмотров (То же, что и выше, я провел много тестов с ними, поэтому то, что я привожу ниже, это только самый последний тест)

class StandingsList(generics.ListCreateAPIView):
    queryset = Season.objects.order_by('-endDate').all()
    serializer_class = StandingsSerializer

    def get_queryset(self):
        season_id = self.request.query_params.get('season_id')
        queryset = SeasonDivisionTeam.objects.filter(season_division__season_id=season_id)
        return queryset

Вернуться на верх