Question

With models defined like so:

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

class Event(models.Model):
    winner = models.ForeignKey(Athlete)
    distance = models.FloatField()

    type_choices = [('LJ', 'Long Jump'), ('HJ', 'High Jump')]
    type = models.CharField(choices=type_choices)

I want to run a query picking out all the events an Athlete has won, grouped by type. I'm currently doing it like so:

athlete = Athlete.objects.get(name='dave')
events_by_type = Events.objects.values('type').annotate(Count('winner')).filter(winner=athlete)

This gives me a dictionary of event types (short versions) and the number of times the athlete has been the winner. However that's all it gives me. If I then want to dig into one of these events to find the distance or even just the verbose type name, I can't.

Am I going about this in the right way? How can I get the events grouped, but also with access to all their fields as well?

Was it helpful?

Solution

You are not getting the event instances because you are querying Event.objects with the values method. This will provide you the data for only the specified fields: https://docs.djangoproject.com/en/dev/ref/models/querysets/#values

Performing this kind of group by with the Django ORM is not straightforward. The proposed solution often is:

q = Events.objects.filter(winner=athlete)
q.query.group_by = ['type']
q.count()

But I'd rather do it with straight python. Maybe something like

athlete = Athlete.objects.get(name='dave')
events = Events.objects.filter(winner=athlete)
won_per_type = defaultdict(list)
for e in events:
    won_per_type(e.type).append(e)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top