2010-05-14 65 views
12

我有2種型號在我的Django代碼:得到一個單一的查詢外鍵對象 - Django的

class ModelA(models.Model): 
    name = models.CharField(max_length=255) 
    description = models.CharField(max_length=255) 
    created_by = models.ForeignKey(User) 

class ModelB(models.Model): 
    category = models.CharField(max_length=255) 
    modela_link = models.ForeignKey(ModelA, 'modelb_link') 
    functions = models.CharField(max_length=255) 
    created_by = models.ForeignKey(User) 

說MODELA有100條記錄,所有這些都可能會或可能不會有聯繫的ModelB

現在說我要與ModelB

數據相處的每MODELA記錄列表

我會做:

list_a = ModelA.objects.all() 

然後讓我會對ModelB數據做

for i in list_a: 
    i.additional_data = i.modelb_link.all() 

但是這個運行在我的每個實例的查詢。從而使101個查詢運行。

是否有所有在短短1查詢運行此的任何方式。或者至少少於101個查詢。

我試圖把在ModelA.objects.select_related().all()但這似乎並沒有產生任何影響。

謝謝

回答

7

由於Ofri說,select_related只適用於遠期的關係,無法扭轉的。

在Django中沒有內置的自動跟隨反向關係的方法,但請參閱my blog post以獲得合理有效的技術。基本思想是一次獲取每個項目的所有相關對象,然後手動將它們與相關項目相關聯 - 因此,您可以在2個查詢中完成,而不是在n + 1個項目中完成。

2

Django ORM是一件好事,但有些事情是更好的手動。 您可以導入連接鼠標和單獨的查詢執行原始的SQL。

from django.db import connection 
cur=connection.cursor() 
cur.execute(query) 
rows = cur.fetchall() 

查詢應該像(爲MySQL

SELECT * FROM appname_modela INNER JOIN appname_modelb ON appname_modela.id=appname_modelb.modela_link_id 
+0

我知道,當使用原始的SQL你不會得到一個對象返回,所以你知道任何方式將結果轉換成一個Django對象 – John 2010-05-14 09:47:00

1

.select_related的原因()沒有工作,是.select_related()是用於跟蹤外鍵。您MODELA沒有一個外鍵ModelB。它的ModelB有一個外鍵MODELA。 (所以MODELA實例可以有與之相關的多個ModelB實例)。

您可以使用它來做到這一點在2個查詢,以及一些Python代碼:

list_b = ModelB.objects.all() 
list_a = ModelA.objects.all() 
for a in list_a: 
    a.additional_data = [b for b in list_b if b.modela_link_id==a.id] 
+1

感謝您。是否有任何性能問題 – John 2010-05-14 10:31:43

相關問題