Django嵌套的QuerySet [英] Django nested QuerySets

查看:48
本文介绍了Django嵌套的QuerySet的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a Django data model like this (data fields omitted):

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(...)上查询,因为其他模型中的所有字段都可以通过外键可以到达.让我们将生成的QuerySet称为 t .

When I query, the fields to be restricted can be in either model, so it is easiest to query on Transition.objects.filter(...) since all fields in the other models can be reached through the foreign keys. Let's call the resulting QuerySet t.

现在我还需要一个与 t 相对应的Atom模型的QuerySet a ,可以像 a = t.values('atom').distinct().到目前为止一切顺利.

Now what I want in addition is a QuerySet a of the Atom model that corresponds to t, which can be done like a = t.values('atom').distinct(). So far so good.

但是,我还希望 a 中的每个条目都具有一个 one 属性/字段,该属性/字段包含该Atom状态的QuerySet,但仍反映了以下条件:原始选择 t ,通过 upstate lostate ForeignKeys之一.

However, I also want each of the entries in a to have one attribute/field that holds the QuerySet for the States of this Atom, still reflecting the criteria on the original selection t, through either one of the upstate or lostate ForeignKeys.

通过循环遍历 t ,添加 values('upstate_id') values('lostate_id'),到目前为止,我已经在States上创建了QuerySet到Python set()以便抛出重复项,然后使用此列表查询状态.但是后来我无法实现原子内部状态的嵌套结构.

I have created my QuerySet on States up to now by looping over t, adding the values('upstate_id') and values('lostate_id') to a Python set() for throwing out duplicates, and then querying States with this list. But then I cannot achieve the nested structure of States within Atoms.

欢迎提供任何有关如何执行此操作的建议,如果可能的话,请使用未评估的 QuerySet s,因为我没有将它们传递给模板,而是传递给了生成器( yield 语句),这是流式传输大量数据的一种好方法.

Any suggestions on how to do this are welcome, if possible with unevaluated QuerySets, since I pass them not into a template but a generator (yield statements), which is a nice way of streaming large amounts of data.

推荐答案

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

I think the following function does what I describe above, but I am not sure if the loop with further filtering of the original QuerySet by atom is the right approach.

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

现在,我可以像这样进行嵌套循环了:

Now I can do the nested loop that I need like this:

someAtoms = getAtomsWithStates( Transition.objects.filter(...) )
for atom in someAtoms:
    for state in atom.States:
        print state.field

但是,再一次,可能会有一个更智能的解决方案,我当然会很感兴趣.

But, once again, there might be a smarter solution for this and I'd surely be interested.

这篇关于Django嵌套的QuerySet的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆