三人加入Django

时间:2017-06-15 22:17:38

标签: sql django join

这是我第一次有一个问题,我在一小时内找不到答案,所以这是我第一次发帖:< / 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, 所以我对这个框架很陌生,并且不了解更高级的技巧。

3 个答案:

答案 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,你可能更喜欢这种方法。