Django 嵌套查询集
我有一个像这样的 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(...)< 上查询是最简单的/code> 因为其他模型中的所有字段都可以通过外键访问。我们将生成的查询集称为
t
。
现在我还想要一个与 t
对应的 Atom 模型的 QuerySet a
,可以像 a = t.values('atom' 那样完成).distinct()
。到目前为止,一切都很好。
但是,我还希望 a
中的每个条目都有 一个 属性/字段,用于保存该 Atom 状态的查询集,仍然反映原始选择的标准t
,通过 upstate
或 lostate
外键之一。
到目前为止,我已经通过循环 t
、添加 values('upstate_id')
和 values('lostate_id')
在 State 上创建了查询集> 到 Python set()
以丢弃重复项,然后使用此列表查询 State。但这样我就无法实现原子内状态的嵌套结构。
如果可能的话,可以使用未评估的 QuerySet 来提供有关如何执行此操作的任何建议,因为我不是将它们传递到模板中,而是传递到生成器(yield
语句)中,这是一个传输大量数据的好方法。
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')
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
.
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.
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.
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.
Any suggestions on how to do this are welcome, if possible with unevaluated QuerySet
s, since I pass them not into a template but a generator (yield
statements), which is a nice way of streaming large amounts of data.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为以下函数执行我上面描述的操作,但我不确定按原子进一步过滤原始 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.
Now I can do the nested loop that I need like this:
But, once again, there might be a smarter solution for this and I'd surely be interested.
很高兴您能够理解
集合
。但是,使用 SQL 的In
不会重复您的数据。让我们考虑一下。如果我说,“给我一个在此列表中的原子:(1, 2, 3, 3, 3, 4)”,数据库将返回原子 1, 2, 3 和 4。为了简化,我不会要求 Python 执行set
算术,因为数据库应该能够很好地处理它。有时需要使用set
,但您的场景似乎不是其中之一。您的替代方案:
即便如此,您的模型似乎可以使用一些更改,但我不完全理解您想要完成的任务。请注意,在我的替代方案中,我不对原子做任何事情。我使用 Q 对象来执行 OR 运算,但您也许可以向状态模型添加一个标志来指示它是高还是低。或者您可以使用带有直通表的 M2M 关系。为什么你的转变和你的状态都与原子相关联?您可以从
Transition
中消除atom
并从State
中获取atom
,如下所示:It is very nice that you have the understanding of
set
s. However, using SQL'sIn
will not duplicate your data. Let's consider that for a moment. If I say, "Give me an atom that is in this list: (1, 2, 3, 3, 3, 4)," the database will return atoms 1, 2, 3, and 4. For simplification, I would not ask Python to perform theset
arithmetic since the database should be able to handle it just fine. There are times to useset
, but your scenario doesn't seem like one of them.An alternative for you:
Even so, it seems like your model could use some changes, but I don't fully understand what you're trying to accomplish. Notice how that in my alternative, I don't do anything with atoms. I use the
Q
object to be able to perform an OR operation, but you might be able to add a flag to the State model to indicate if it is high or low. Or you could use an M2M relation with a through table. And why would your transition and your state both be associated with an atom? You could just eliminateatom
fromTransition
and get theatom
fromState
like so: