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_team
和 away_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'
大家好,我在尝试构建此端点的工作方式时遇到了一些问题。目前,我希望这个端点 "/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_team
和 away_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'