复杂Django查询创建字典

时间:2015-11-26 16:14:20

标签: django django-models

models.py

class Event(models.Model):
    name = models.CharField(max_length=100)
    date = models.DateField()

class Result(models.Model):
    event = models.ForeignKey(Event)
    place = models.IntegerField()
    person = models.CharField(max_length=100)
    gender = models.CharField(max_length=1)
    score = models.IntegerField()

事件样本数据:

id, name, date
1, 'event1', '2015-01-01'
2, 'event2', '2015-02-01'
3, 'event3', '2015-03-01'

结果样本数据:

event_id, place, person, gender, score
1, 1, 'al', 'M', 25
1, 2, 'bob', 'M', 22
1, 3, 'cindy', 'F', 21
1, 4, 'doug', 'M', 20
2, 1, 'elen', 'F', 30
2, 2, 'frank', 'M', 28
2, 3, 'gord', 'M', 20
2, 4, 'helen', 'F', 19

我想查询这个并获得一个字典,其中包含每个活动的男性和女性获奖者(有分数):

winnersdict = {event_id: (mwinner, mscore, fwinner, fscore), ...}

在这种情况下,结果字典将是:

{1: ('al', 25, 'cindy', 21), 2: ('frank', 28, 'elen', 30). 3: (None, None, None, None)}

现在我这样做:

events = Event.objects.all().order_by('date')
winnersdict = {}
for e in events:
    femalewinner = Result.objects.filter(event_id=e.id, gender='F')[:1]
    if len(femalewinner) == 0:
        fwinner = None
        fscore = None
    else:
        fwinner = femalewinner[0].person
        fscore = femalewinner[0].score
    malewinner = Result.objects.filter(event_id=e.id, gender='M')[:1]
    if len(malewinner) == 0:
        mwinner = None
        mscore = None
    else:
        mwinner = malewinner[0].person
        mscore = malewinner[0].score
    winnersdict[e.id] = (mwinner, mscore, fwinner, fscore)

当然有一种更聪明的方法。我将有成千上万的事件,通过这种方式循环似乎很糟糕。如果它简化了一些事情我也可以生成一个单独的femalewinnersdict和malewinnersdict。如果我们将“无”字体排除在结果字典之外,我也可以(甚至可能更喜欢),对于这种情况,我对那些还没有结果的事件不感兴趣。< / p>

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

请尝试以下查询,它会分别给你男性/女性。

from django.db.models import Max

male_results = Event.objects.filter(result__gender='M') \
                            .annotate(max_score=Max('result__score')) \
                            .values('name', 'result__person', 'result__score')