2017-09-23 97 views
0

獲得從模型信息,我有這兩種模式:使用不相關的領域

class A(models.Model): 
    name=models.CharField(max_length=10) 

class D(models.Model): 
    code=models.IntegerField() 

代碼字段可以有許多存在於模型A,但它不能由於其它因素有關。但我想知道的是列出從A,其值是相同的代碼

items=D.objects.values('code__name') 

的工作,但因爲它們是不相關的,也可以進行相關的項目,我該怎麼處理這個問題?

+0

代碼字段可以有許多存在於模型A - 你是什麼意思?模型A中的代碼== pk? –

+0

@BearBrown是的,它認爲存在於模型號碼A –

回答

1

可以使用django extra,你的真正的應用程序名稱替換YOUAPP

D.objects.extra(select={'a_name': 'select name from YOUAPP_a where id=code'}).values('a_name') 
#           Replace YOUAPP^^^^^ 
+0

+1:因爲'.extra()'方法是必要的,不久前Django的1.11之前,但它是一個安全警告和注意事項相關的「使用此方法最後的手段。「 (文檔)。我的經驗是它有許多意想不到的侷限和後果,包括「替換YOUAPP」。我覺得新的查詢表達式非常友好。 – hynekcer

+0

如果使用'.values('a_name')',那麼結果只有該字段。這是無用的。 (可以用很多方法修改,是的,有時候必須是字段名重複的值)。這就是我的意思是,正確使用extra()方法的規則即使在經歷了很長時間之後也不容易記住。 – hynekcer

0

可以在使用Subquery() expressions Django的1.11或更高版本。

from django.db.models import OuterRef, Subquery 

code_subquery = A.objects.filter(id=OuterRef('code')) 
qs = D.objects.annotate(code_name=Subquery(code_subquery.values('name'))) 

qs的輸出是具有添加的字段code_name對象D的查詢集。


腳註:

它編譯成一個非常類似的SQL(像熊布朗與「額外」的方法解決方案,但沒有他的解決方案的缺點,看到那裏):

SELECT app_d.id, app_d.code, 
     (SELECT U0.name FROM app_a U0 WHERE U0.id = (app_d.code)) AS code_name 
FROM app_d 

如果需要字典輸出,最終可以通過.values()進行轉換。它可以像左連接一樣工作,即如果僞相關字段允許爲空(code = models.IntegerField(none=True)),則對象D不受限制,並且輸出code_name值可以爲無。子查詢的一個特性是它只返回一個字段表達式,必須最終重複其他字段。 (這類似於extra(select={...: "SELECT ..."}),但由於對象語法它可以比一個明確的SQL更具可讀性定製)。