我有一个丑陋的循环,在Django中作为创可乐运行,我想优化成一个连接。我把它分解为最基本的结构,以帮助简化问题。我希望别人之前碰到过这样的事情 - 如果没有,我会在最后修复时分享答案。
总结
我确信拥有更多数据库经验的人可以说得更好(如果您对此关联有更好的描述,请发表评论)。
以下是我在Django中使用的结构的简单示例,以及正在运行的循环类型:
class ObjectA(models.Model):
object_a_rules = models.ManyToManyField("self", symmetrical=False, through='ObjectARule')
class ObjectARule(models.Model):
object_a_one = models.ForeignKey(ObjectA, related_name="object_a_before")
object_a_two = models.ForeignKey(ObjectA, related_name="object_a_after")
class ObjectB(models.Model):
object_a_association = models.ForeignKey(ObjectA)
def that_annoying_loop_i_mentioned(self):
object_a_rules_list = ObjectARule.objects.filter(object_a_one = self.object_a_association)
#A list of all of the ObjectARules that have the ObjectA this ObjectB is associated with
#as the first half of the many-to-many relationship.
object_b_list = ObjectB.objects.all()
#A list of all of the ObjectBs, may also be a filtered list
for object_a_rule in object_a_rules_list:
for object_b in object_b_list:
if (object_a_rule.object_a_two == object_b.object_a_association):
#if the second half of ObjectARule is the ObjectA of
#the ObjectB in this list, then do something with that ObjectB.
pass
Django如何通过连接获取ObjectB的列表,所以这个非常低效的循环不必运行?
答案 0 :(得分:2)
给定一个ObjectB,我需要一组 其他作为子节点的ObjectB 与之关联的ObjectAs 使用我们的ObjectB的父ObjectA。
如果objb
是你给出的ObjectB,你可以这样做:
objects = ObjectB.objects.filter(object_a_association__object_a_rules=objb.object_a_association)
或者,
objects = ObjectB.objects.filter(object_a_association__object_a_rules__objectb_set=objb)