Django / DRF - конечная точка API REST с параметром запроса, который отправляет запросы нескольким конечным точкам - PullRequest
0 голосов
/ 20 сентября 2019

Эй, ребята, у меня возникли проблемы с попыткой спроектировать, как будет работать эта конечная точка.В настоящее время я хотел бы, чтобы эта конечная точка "/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?

чтобы получить параметры, но я не уверен, как оттуда идти.

edit - Добавлены мои модели ниже -

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()

1 Ответ

1 голос
/ 20 сентября 2019

Пожалуйста, удалите _id из всех ваших полей ForeignKey, это создает очень запутанный код: если у вас есть экземпляр Player, то player.team_id - это экземпляр Team (не идентификатор команды)и player.team_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')

Здесь я изменил ваши related_name в полях home_team и away_team, потому что они используются для отношений 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'
...