hebius
hebius

Reputation: 133

Django aggregation/annotation

I have (it's just an example) models like these:

class Team(models.Model):
    name = models.CharField(...)


class Player(models.Model):
    name = models.CharField(...)


TeamHasPlayer(models.Model):
    team = models.ForeignKey(Team)
    player = models.ForeignKey(Player)

I need to make a dictionary like this:

{
    'Team_1': [Player_1, Player_2, ...],
    'Team_2': [Player_3, Player_4, ...],
    ...
 }

I thought it can be achieved with django annotation/aggregation tools, I read all the docs about it, tried many different approaches but I can't achieve what I want. Could anyone give me any hint? I don't want to do any asking-db-in-for-loop things so I decided to use aggregations/annotations.

Upvotes: 0

Views: 88

Answers (2)

Todor
Todor

Reputation: 16010

Here is what you can do:

  1. You have a M2M relation between Team and Player, create it.

    class Player(models.Model):
        name = models.CharField(...)
    
        teams = models.ManyToManyField(Team, through='TeamHasPlayer')
    
  2. Get your Team queryset and using the reverse relation prefetch the team.players

    teams = Team.objects.all().prefetch_related('player_set')
    
  3. Now create your team dict:

    team_dict = {}
    for team in teams:
        team_dict[team.name] = list(team.player_set.all())
    

Upvotes: 1

doniyor
doniyor

Reputation: 37856

I would do this in this way, which is more readable and maintainable.

dic_ = {}
for team in Team.objects.all():
    dic_[team.name] = team.teamhasplayer_set.values_list('player', flat=True)

Upvotes: 0

Related Questions