繁体   English   中英

根据另一个模型的外键有效地对一个模型进行分组

[英]Efficiently grouping one model based on another's ForeignKey

我大致有两种模型:

class Event(model.Model):
    pass

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

给定N个可能的grades ,我想将Event分为N + 2组:

  • Event ,其中给定Event的所有Judgement都相同(N个组)
  • Event s的任何Judgement
  • Judgement相互冲突的Event

到目前为止,我只想统计所有组的数量,或者是其中一个组的结果。 我有一些非常丑陋的代码,我在其中遍历所有查看<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)

另一种选择是保存Judgement对象时确定Event所属的组,但是如果可以避免的话,可以。

如何使用聚合函数? 这就是我要做的:

  • 首先,将您的一对多关系命名为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)

希望这可以帮助 :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM