2015-07-01 113 views
0

全系車型在我所定義的模型名爲ServerDjango的選擇與外鍵

class Server(models.model): 

和一堆使用該模型作爲一個外鍵

class ServerInfo(models.Model): 
    server = models.ForeignKey(server, null=True) 
class ServerDNSRecord(models.Model): 
    server = models.ForeignKey(server, null=True) 
...etc 

現在車型Django的web應用程序我有一個API調用,返回一個服務器及其所有附加信息。目前我只是爲每個服務器做一個for循環,並用服務器的名稱搜索每個信息表。問題是有時我需要進行一次API調用,以返回所有服務器及其信息。

這會爲數據庫創建大量的SQL查詢,並且此調用的響應時間通常大於5秒,這是不可接受的。

是否有任何簡單的方法來做某種聯接或外鍵搜索來減少數據庫調用的數量來加快速度?

+1

'select_related'可能是你想要的:https://docs.djangoproject.com/en/1.8/ref/models/querysets/#select-related – NightShadeQueen

回答

2

你想要的是在你將要抓取的所有相關類型上執行select_related。例如:

res = Server.objects.prefetch_related("serverinfo_set", "serverdnsrecord_set", ...).first() 
res.serverinfo_set # Won't need another query 
res.serverdnsrecord_set # Won't need another query 

另外,如果你想自動地做到這一點,你可以這樣做:

related_fieldnames = [f.get_accessor_name() for f in Server._meta.get_all_related_objects()] 
res = Server.objects.prefetch_related(*related_fieldnames).first() 
res.serverinfo_set # Won't need another query 
res.serverdnsrecord_set # Won't need another query 

我要指出的是,如果這個應用程序得到重用,並有人開始會附上更多ForeignKeys到服務器是那些都將獲得select_related當然。

+0

我很困惑,因爲在django文檔中它看起來像select_related是用於與我想要做的相反的事情。那就是你選擇與外鍵相關的模型,並找到模型表。我也收到一個錯誤,指出Query_Set沒有屬性find_one,所以我不認爲這是一個有效的方法。 – Josh

+0

@Josh呃,首先意味着()不find_one(),太多的mongodb。 – CrazyCasta

+0

此外,您對文檔的評論是準確的,這有點令人困惑。但是,iirc select_related只是在你使用'.'後用相同的名字來操作數據,並在隨後使用'.'的地方使用'__'(就像'res.serverinfo_set.someother_foreign_key'將是'serverinfo_set__someother_foreign_key ' – CrazyCasta