这是我第一次有一个问题,我在一小时内找不到答案,所以这是我第一次发帖:< / p>
如何在Django中进行三重连接?这是我已有的最小版本:
class A(models.Model):
x = models.ForeignKey(X)
y = models.ForeignKey(Y)
class B(models.Model):
y = models.ForeignKey(Y, related_name="Bs")
z = models.ForeignKey(Z)
value = models.IntegerField(default=0)
class C(models.Model):
x = models.ForeignKey(X)
z = models.ForeignKey(Z)
value = models.IntegerField(default=0)
def updateA():
as = A.objects.all()
for a in as:
for b in a.y.Bs:
if b.value <= C.objects.get(x=a.x, z=b.z).value:
<a.stuff = b.stuff>
我真正想要的是表A,B和C之间的三重连接, 其中a.x = c.x,a.y = b.y,b.z = c.z,AND b.value&lt; = c.value, 虽然在验证b.value&lt; = c.value后我不在乎c。
Django有没有办法在数据库中完成更多这项工作?
我遇到的问题是Django似乎固有地关注 双向连接,我不知道如何进行三向连接。
然后,我在6周前还没有认识任何Django或Python, 所以我对这个框架很陌生,并且不了解更高级的技巧。
答案 0 :(得分:0)
试试这个
A.objects.all().extra(tables=['"table_a" AS "t1"', '"table_b" AS "t2"', '"table_c" AS "t3"'], where=['t1.x=t3.x AND t1.y=t2.y AND t2.z=t3.z AND t2.value <= t3.value'])
将上述查询'table'
中的这些字符串中的应用名称(小写)的'table_a','table_b','table_c'
字符串重新发送到您的应用名称
答案 1 :(得分:0)
我按照NeErAj KuMaR的建议,根据额外情况选择了以下内容,但我必须首先解决一些问题(将_id添加到外键,将变量名称放在&#34;&#34;以保护大写字母,并使用myapp_a而不是选择表A的另一个副本作为重命名为t1)。基本上,我们通过&#39; select&#39;选择表t2中的新值,对所有三个表进行连接,强制执行约束,最后得到需要更新的As列表:
as = A.objects.all().extra(select={'nextY_id' : 't2."nextY_id"'}, tables=['"myapp_b" AS "t2"', '"myapp_c" AS "t3"'], where=['t2.deleted = false AND t2.minimum <= t3."baseValue" AND myapp_a."x_id"=t3."x_id" AND myapp_a."y_id"=t2."y_id" AND t2."z_id"=t3."z_id"']).only('x_id','y_id').distinct('id') # extra does not quote to protect uppercase letters.
for a in as:
f(a.x_id, a.y_id, oldValue=True)
a.y_id = a.nextY_id # a.y_id is updated, a.y is not.
f(a.x_id, a.y_id)
a.save()
答案 2 :(得分:-3)
Django的ORM不太适合复杂的数据模型或查询表达式。您可以花费更多的精力尝试使用Django完成某些操作,而不是编写一些SQL来完成它。您可以利用Django的表单和验证例程,而无需使用Djanogo的ORM。如果你有一个简单的数据模型,你已经知道SQL,你可能更喜欢这种方法。