2017-06-15 23 views
0

這是我第一次有一個問題,我找不到一個小時內在這裏搜索的答案,所以這是我第一次不得不發帖:三人加入Django

如何在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, 其中Ax = CX和ay =通過,BZ = CZ,之間的三重加盟b.value < = c.value, 雖然我不關心c後驗證b.value < = c.value。

Django有沒有辦法在數據庫中完成更多這項工作?

我的問題是,Django似乎固有地集中在 雙向連接,我不知道如何進行三向連接。

再說一遍,我6周前不知道任何Django或Python, ,所以我是這個框架的新手,不知道更高級的技巧。

+0

爲什麼你會讓這個x,y,a,b無意義的幫手變得更加困難嗎? – e4c5

回答

0

我用下面去的基礎上,額外的,如由NeErAj KuMaR建議,儘管我必須首先解決一些問題(將_id添加到外鍵,將變量名放在「」以保護大寫字母,並使用myapp_a而不是選擇表A的另一個副本,將其重命名爲t1) 。基本上,我們選擇了從表t通過「選擇」的新值,做一個連接在所有三個表,強制約束,並與作爲需要被更新的列表結束:

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() 
-3

Django的ORM不適合複雜的數據模型或查詢表達式。你可以花費更多的精力,試圖用Django完成某些工作,而不是編寫一些SQL來完成它。您可以充分利用Django的表單和驗證例程,而不必使用Djanogo的ORM。如果你只有一個簡單的數據模型,並且你已經知道SQL,那麼你可能更喜歡這種方法。

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']) 

Replce 'table'字符串應用程序名稱(小寫)從上面的查詢'table_a','table_b','table_c'這些字符串的程序名稱

+0

此解決方案的問題: 1)您無法直接比較t1.x和t3.x。你需要t1.x_id和t3.x_id 2)這並不奏效,因爲你想把原始表格作爲t1,而不是補充,所以你想要x_id = t3.x_id 3)這並不完美工作,因爲x_id不明確,因爲它存在於兩個表中。 4)如果不是x_id,我們有xX_id,這會失敗,因爲django會將其轉換爲xx_id,但它會在數據庫中爲xX_id,導致找不到xx_id列,提示:您的意思是xX_id? – user8168634

+0

阻止錯誤:如果任何列名稱包含大寫字母,則這不起作用。 – user8168634

+0

https://code.djangoproject.com/ticket/28317#ticket – user8168634