Django/DRF - REST API 带有查询参数的端点可以查询多个端点

Django/DRF - REST API endpoint with query parameter that goes queries multiple endpoints

大家好,我在尝试构建此端点的工作方式时遇到了一些问题。目前,我希望这个端点 "/nba/players?date=01012016" 可以通过两个不同的端点来获得结果。

目前我的 GameDates 端点 return 类似于

{id: 1, home_team_id: 1, away_team_id: 2, date: "1/1/2016"},
{id: 4, home_team_id: 2, away_team_id: 3, date: "1/2/2016"}

我想获取 GameDate_id 或者它的主键(在本例中为 id:1),然后将其传递到另一个 PlayerStatistic 端点​​,该端点将 return 像这样 -

{id: 1, game_id: 1, player_id: 1, team_id: 1, points: 20, assists: 10, rebounds: 2},
{id: 2, game_id: 1, player_id: 2, team_id: 1, points: 15, assists: 2, rebounds: 2},
{id: 3, game_id: 1, player_id: 3, team_id: 2, points: 10, assists: 2, rebounds: 20},
{id: 4, game_id: 1, player_id: 4, team_id: 2, points: 5, assists: 1, rebounds: 2}

我的日期查询初始端点将 return 这四个 JSON 因为玩家在那个日期(game_id = 1)从 GameDate 端点玩了一场游戏,然后game_id习惯查询 PlayerStatistic 端点​​和 returns.

我知道重写 get_queryset 函数的正确方法,例如 -

 def get_queryset(self):
        date = self.request.query_params.get('date')
        queryset = self.queryset
        if date:
            # the rest here?

获取参数,但我不确定如何从那里开始。

编辑 - 在下面添加了我的模型 -

class Player(models.Model):
    # class for Player model

    name = models.CharField(max_length=100)
    team_id = models.ForeignKey(Team, on_delete=models.CASCADE)


class GameDate(models.Model):
    # class for GameDate model

    home_team_id = models.ForeignKey(Team, related_name='home_games',
                                     on_delete=models.CASCADE)
    away_team_id = models.ForeignKey(Team, related_name='away_games',
                                     on_delete=models.CASCADE)
    date = models.DateField()


class PlayerStatistic(models.Model):
    # class for individual player statistics

    game_id = models.ForeignKey(GameDate, on_delete=models.CASCADE)
    player_id = models.ForeignKey(Player, on_delete=models.CASCADE)
    team_id = models.ForeignKey(Team, on_delete=models.CASCADE)
    points = models.IntegerField()
    assists = models.IntegerField()
    rebounds = models.IntegerField()

请从所有 ForeignKey 字段中删除 _id,这会使代码非常混乱:如果您有一个 Player 实例,那么 player.team_id 是一个 Team 实例(不是团队的 id)和 player.team_id_id 是 id。看看有多混乱?

因此,假设您已删除所有 _id,以下是获取特定日期的所有玩家统计数据的方法:

PlayerStatistics.objects.filter(game__date=date)
# or inside `get_queryset(self)`:
super().get_queryset().filter(game__date=date)

您可以进一步按比赛排序(如果同一天有不止一场比赛),然后是球队和最高分:

PlayerStatistics.objects.filter(game__date=date).order_by('game', 'team', '-points') 

date 需要是一个 datetime.date 对象,因此如果您的输入是字符串,请确保先将其转换为正确的日期对象。

如果您实际上列出了特定日期的 Player 个实例(并希望嵌套每个玩家的相关统计数据):

Player.objects.filter(
      Q(team__home_games__date=date) 
    | Q(team__away_games__date=date))\
              .prefetch_related('playerstatistics')

我在这里更改了 home_teamaway_team 字段中的 related_name,因为它们用于 reverse 关系你可以在这里看到(从团队到游戏)所以他们应该包含单词 games 而不是 team.

如果您只想要已记录统计数据的球员,那么试试这个:

from django.db.models import Exists, OuterRef

player_stats = PlayerStatistics.objects.filter(game__date=date, player=OuterRef('pk'))
Player.objects.filter(
      Q(team__home_games__date=date) 
    | Q(team__away_games__date=date))\
        .annotate(has_stats=Exists(player_stats))
        .filter(has_stats=True)
        .prefetch_related('playerstatistics'