Python 基于另一个模型高效地分组';外键

Python 基于另一个模型高效地分组';外键,python,django,django-models,Python,Django,Django Models,我大致有两种模型: class Event(model.Model): pass class Judgement(model.Model): grade = models.CharField() event = models.ForeignKey(Event) 考虑到N个可能的等级,我想将事件分为N+2组: 事件s,其中给定事件的所有判断s均相同(N组) 事件s无判断 事件s与判断冲突s 到目前为止,我只想计算所有组的计数,或者其中一个组的结果。我有一些非常难看的

我大致有两种模型:

class Event(model.Model):
    pass

class Judgement(model.Model):
    grade = models.CharField()
    event = models.ForeignKey(Event)
考虑到N个可能的
等级
,我想将
事件
分为N+2组:

  • 事件
    s,其中给定
    事件
    的所有
    判断
    s均相同(N组)
  • 事件
    s无
    判断
  • 事件
    s与
    判断冲突
    s
到目前为止,我只想计算所有组的计数,或者其中一个组的结果。我有一些非常难看的代码,我只是在所有对象中循环查看
\u set
属性,但它似乎没有有效地使用Django的ORM:

获取所有组的计数
def事件组计数()
data=defaultdict(int,{})
events=Event.objects.prefetch\u related('判断集').all()
对于事件中的事件:
等级=集合(e.事件中e的等级。判断\u集合。全部()
如果len(等级)>1:
数据['disagree']+=1
elif len(等级)<1:
数据['unjudged']+=1
其他:
数据[grades.pop()]+=1
把所有的人都聚集在一起
def事件组(组):
结果=[]
events=Event.objects.prefetch\u related('判断集').all()
对于事件中的事件:
等级=集合(e.事件中e的等级。判断\u集合。全部()
如果len(等级)>1且组=“不同意”:
results.append(事件)
elif len(等级)<1且组=‘未编入预算’:
results.append(事件)
elif group==grades.pop():
results.append(事件)
另一种选择可能是,在保存
判断
对象时,确定
事件
所属的组,但如果我可以避免,那么是的。

使用该方法如何

  • 首先,命名您的一对多关系
    event=models.ForeignKey(事件,相关的\u name='justions')
  • 对于计数,执行如下操作
    q=Event.objects.annotate(计数('judgements'),distinct=True)
    。您可以使用
    判断\u计数
    访问此新字段
  • 要检索特定组,请使用筛选和排序:
也许是这样的:

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)

希望这有帮助:)

中的id\u会导致我的数据库接口在达到数千个时死亡<代码>操作错误:SQL变量太多
。我还在考虑这个问题。
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)
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)