Django嵌套查询集

2024-10-01 13:24:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这样一个Django数据模型(省略数据字段):

class Atom(Model):
    pass

class State(Model):
    atom = ForeignKey(Atom)

class Transition(Model):
    atom = ForeignKey(Atom)
    upstate = ForeignKey(State,related_name='uptrans')
    lostate = ForeignKey(State,related_name='lotrans')

当我查询时,要限制的字段可以在任何一个模型中,因此在Transition.objects.filter(...)上查询是最容易的,因为其他模型中的所有字段都可以通过外键访问。让我们调用结果查询集t。在

现在我想要的是原子模型的一个查询集a,它对应于t,可以像a = t.values('atom').distinct()一样完成。到现在为止,一直都还不错。在

但是,我还希望a中的每个条目都有一个属性/字段,该属性/字段保存该原子状态的查询集,仍然通过upstatelostate之一反映原始选择t的条件。在

到目前为止,我已经创建了关于状态的查询集,方法是循环使用t,将values('upstate_id')和{}添加到Pythonset()以抛出重复项,然后使用此列表查询状态。但是我不能得到原子内部的嵌套态结构。在

任何关于如何做到这一点的建议都是受欢迎的,如果可能的话,可以使用未赋值的QuerySets,因为我将它们传递到一个生成器(yield语句),这是流式传输大量数据的好方法。在


Tags: name模型model状态classatomstatevalues
2条回答

我认为下面的函数实现了我上面描述的功能,但是我不确定用atom进一步过滤原始QuerySet的循环是否是正确的方法。在

def getAtomsWithStates(t):
    atom_ids = set( t.values_list('atom_id',flat=True) )
    atoms = Atoms.objects.filter(pk__in=atom_ids)
    for atom in atoms:
        upstate_ids = t.filter(atom=atom).values_list('upstate_id',flat=True)
        lostate_ids = t.filter(atom=atom).values_list('lostate_id',flat=True)
        all_ids = set( upstate_ids + lostate_ids )

        # attach the new QuerySet to the entry in the outer one:
        atom.States = State.objects.filter(pk__in=all_ids)

    return atoms

现在我可以这样做我需要的嵌套循环:

^{pr2}$

但是,再一次,可能有一个更聪明的解决办法,我肯定会感兴趣的。在

sets的理解是非常好的。但是,使用SQL的In不会复制数据。让我们考虑一下。如果我说,“给我这个列表中的一个原子:(1,2,3,3,3,4)”,数据库将返回原子1,2,3,和4。为了简化起见,我不会要求Python执行set算法,因为数据库应该可以很好地处理它。有时可以使用set,但您的场景似乎不是其中之一。在

你的另一种选择:

states = State.objects.filter(
    Q(pk__in=t.values_list('upstate', flat=True)) |
    Q(pk__in=t.values_list('lostate', flat=True)
)

即便如此,你的模型似乎需要一些改变,但我不完全理解你想要实现什么。注意,在我的选择中,我对原子什么都不做。我使用Q对象来执行OR操作,但是您可以向状态模型添加一个标志来指示它是高还是低。或者你可以使用一个M2M关系和一个通表。为什么你的跃迁和你的状态都与原子有关?您可以从Transition中消除atom,然后从State中得到{},如下所示:

^{pr2}$

相关问题 更多 >