Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django/DRF-RESTAPI端点,带有查询多个端点的查询参数_Python_Django_Rest_Django Rest Framework_Endpoint - Fatal编程技术网

Python Django/DRF-RESTAPI端点,带有查询多个端点的查询参数

Python Django/DRF-RESTAPI端点,带有查询多个端点的查询参数,python,django,rest,django-rest-framework,endpoint,Python,Django,Rest,Django Rest Framework,Endpoint,嘿,伙计们,我在设计这个端点如何工作时遇到了一些麻烦。目前,我希望这个端点“/nba/players?date=01012016”通过两个不同的端点来获得结果 目前,我的GameDates端点返回类似于 {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或它的主键(在本例中为

嘿,伙计们,我在设计这个端点如何工作时遇到了一些麻烦。目前,我希望这个端点
“/nba/players?date=01012016”
通过两个不同的端点来获得结果

目前,我的GameDates端点返回类似于

{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端点,该端点将返回如下内容-

{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}
我的带有日期查询的初始端点将返回这四个JSON,因为玩家在该日期(game_id=1)从GameDate端点有一个游戏,然后该game_id用于查询 PlayerStatistic端点和返回

我知道覆盖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()


请从所有
外键
字段中删除
\u id
,这会造成非常混乱的代码:如果你有
玩家
实例,那么
玩家。团队id
是一个
团队
实例(不是团队id),而
玩家。团队id
是id。看看有多混乱

因此,假设您已删除所有
\u 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
实例(并希望嵌套每个玩家的相关统计数据):

在这里,我更改了
主队
客队
字段中的
相关
名称,因为它们用于反向关系,正如您在这里看到的(从一个队到另一个比赛),因此它们应该包含
比赛
而不是
球队

如果您只想要已记录统计数据的播放器,请尝试以下操作:

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'

你想错了。您不能从另一个端点调用端点,至少没有必要这样做。您只需调用playerstats端点,并根据日期正确筛选玩家查询集。向我们展示您的游戏和玩家模型(或玩家统计)。@DirkRoten我已经用我的模型更新了我的帖子。如果没有日期,您希望url/players从PlayerViewset返回结果,这有点奇怪,但是如果有日期作为查询参数,它将返回一个完全不同的资源,即PlayerStatisticsViewset。它应该返回相同的列表,但以某种方式使用日期进行过滤。您可能希望将/players和/player stats分离为不同的URL。在设计API时,仔细考虑各种URL是很重要的。资源
游戏
的良好REST API是:获取/games/返回
游戏
列表,可以添加过滤器(/games/?date=xxx)。发布/游戏/创建新游戏。GET/games/id获取特定游戏,POST/games/id更新现有游戏。删除有点棘手(应该是Delete/games/id,但浏览器不执行删除),所以我通常会执行POST/games/id/Delete。这在我看来很好,“返回在特定日期玩过的所有玩家”将是
Player.objects.filter(Q(team\u home\u games\u date=date)| Q(team\u away\u games\u date=date))
然后在序列化程序中,如果你想添加统计数据,只需为玩家嵌套
PlayerStatistics
。但这一切都在
PlayerViewSet
中,没错。提到
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'