基于另一个的ForeignKey有效地对一个模型进行分组

时间:2014-08-25 09:49:55

标签: python django django-models

我有两个模型,大概是:

class Event(model.Model):
    pass

class Judgement(model.Model):
    grade = models.CharField()
    event = models.ForeignKey(Event)

鉴于N可能grades,我想将Event分为N + 2组:

  • Event s,其中给定Judgement的所有Event都是相同的(N组)
  • Event s没有Judgement
  • Event s有冲突的Judgement s

到目前为止,我只想要所有组的计数,或其中一组的结果。我有一些非常丑陋的代码,我只是遍历查看<foreignkey>_set属性的所有对象,但它似乎没有有效地使用Django的ORM:

获取所有组的计数

def event_group_counts():
    data = defaultdict(int, {})
    events = Event.objects.prefetch_related('judgement_set').all()
    for event in events:
        grades = set(e.grade for e in event.judgement_set.all())
        if len(grades) > 1:
            data['disagree'] += 1
        elif len(grades) < 1:
            data['unjudged'] += 1
        else:
            data[grades.pop()] += 1

获得所有一组

def event_group(group):
    results = []
    events = Event.objects.prefetch_related('judgement_set').all()
    for event in events:
        grades = set(e.grade for e in event.judgement_set.all())
        if len(grades) > 1 and group == 'disagree':
            results.append(event)
        elif len(grades) < 1 and group == 'unjudged':
            results.append(event)
        elif group == grades.pop():
            results.append(event)

备选方案可能是确定Event对象保存时Judgement所属的组,但如果我可以避免,那么就是。

1 个答案:

答案 0 :(得分:0)

如何使用aggregation functions?我会这样做:

  • 首先,将您的一对多关系命名为event = models.ForeignKey(Event, related_name='judgements')
  • 为了计算,请执行此类q = Event.objects.annotate(Count('judgements'), distinct=True)之类的操作。您可以使用judgements__count
  • 访问此新字段
  • 用于检索某个组,使用过滤和排序:

也许是这样的:

def event_group(group):

    # unjudged is a special case, you just get all events with an empty set of judgements 

    judgements = Judgement.objects.filter(grade=group_id).order_by(event)
    event_ids = [j.event for j in set(judgements)]
    return Event.objects.filter(id__in=event_ids)

希望这会有所帮助:)