Вложенные сериализаторы Django Rest Framework с несколькими типами фильтров запросов
Извините за не очень описательное название, трудно выразить словами то, что я пытаюсь сделать.
Мои модели имеют различные отношения "многие ко многим". Я пытаюсь заставить мои сериализаторы действовать очень похоже на запросы, которые я перечислил ниже. По сути, я хочу получить модель TeamStats, сериализованную различными способами. Если мне нужна статистика всей лиги, я фильтрую по сезону, если только одной команды, я фильтрую по команде и т.д. Эти запросы также будут только для чтения, они не будут записываться, они предназначены только для просмотра на фронт-энде.
Кроме того, мне нужно, чтобы сериализатор был вложен таким образом, чтобы все, что фильтрует запрос, было верхними данными в JSON. Например, если бы я делал TeamStats по сезонам, я бы имел дивизион, вложенный в сезон, команду, вложенную в дивизион. Если бы я просто вызывал TeamStats по дивизионам, я бы имел просто Team, вложенную в Division.
Модели
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 SeasonTest(BaseModel):
name = models.CharField(max_length=50)
class DivisionTest(BaseModel):
name = models.CharField(max_length=50)
seasons = models.ManyToManyField(SeasonTest, through='SeasonDivision')
class SeasonDivision(models.Model):
id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
division = models.ForeignKey(DivisionTest, on_delete=models.CASCADE)
season = models.ForeignKey(SeasonTest, on_delete=models.CASCADE)
class TeamTest(BaseModel):
name = models.CharField(max_length=50)
season_divisions = models.ManyToManyField(SeasonDivision, through='SeasonDivisionTeam')
class SeasonDivisionTeam(models.Model):
id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
team = models.ForeignKey(TeamTest, on_delete=models.CASCADE)
season_division = models.ForeignKey(SeasonDivision, on_delete=models.CASCADE)
class PlayerTest(BaseModel):
season_division_teams = models.ManyToManyField(SeasonDivisionTeam, through='SeasonDivisionTeamPlayer')
firstName = models.CharField(max_length=80)
class SeasonDivisionTeamPlayer(models.Model):
id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
player = models.ForeignKey(PlayerTest, on_delete=models.CASCADE)
season_division_team = models.ForeignKey(SeasonDivisionTeam, on_delete=models.CASCADE)
class PlayerStatsTest(BaseModel):
season_division_team_player = models.ForeignKey(SeasonDivisionTeamPlayer, on_delete=models.CASCADE)
goals = models.IntegerField(default=0)
class TeamStatsTest(BaseModel):
season_division_team = models.ForeignKey(SeasonDivisionTeam, on_delete=models.CASCADE)
regWins = models.IntegerField(default=0)
Примеры запросов
season = SeasonTest.objects.get(name='Spring 2022')
division = DivisionTest.objects.get(name='WEEKNIGHT NOVICE')
team = TeamTest.objects.get(name='CHAOS')
player = PlayerTest.objects.get(firstName='Misty', lastName='Thompson', jerseyNumber=72)
# Standings (Stats for the whole league for a given season)
teamStatsBySeason = TeamStatsTest.objects.filter(season_division_team__season_division__season=season)
# Team Stats for only a given division
teamStatsByDivision = TeamStatsTest.objects.filter(season_division_team__season_division__division=division)
# Team Stats for only a given team
teamStatsByTeam = TeamStatsTest.objects.filter(season_division_team__team=team)
# All Player stats for a given season
playerStatsBySeason = PlayerStatsTest.objects.filter(
season_division_team_player__season_division_team__season_division__season=season)
# Player Stats for a given Division
playerStatsByDivision = PlayerStatsTest.objects.filter(
season_division_team_player__season_division_team__season_division__division=division)
# Player Stats for a given Team
playerStatsByTeam = PlayerStatsTest.objects.filter(
season_division_team_player__season_division_team__team=team)
# Player Stats for a given Player
playerStatsByPlayer = PlayerStatsTest.objects.filter(
season_division_team_player__player=player)