2014-12-25 21 views
0

12月29日:更新機型Django的:如何使用select_related於INNER JOIN FK的FK

我有三個型號如下:

class Job(models.Model): 
    job_number = models.CharField(max_length=20, primary_key=True) 

class Project(models.Model): 
    job = models.ForeignKey(Job, null=True) # updated (null=True)*** 
    source = models.ForeignKey(Source) # added*** 

class Task(models.Model): 
    project = models.ForeignKey(Project) 

class Source(models.Model): # added*** 
    blahblah... 

而且我想獲得的工號一個任務。像下面這樣:

job = Job.objects.all().select_related() 
jobno = job[0].project.job.job_number 

我不知道上面的查詢會碰到數據庫多少次。但我想這會超過兩倍,不是嗎?

select_related只能預先緩存2個表的外鍵才能理解。任何人都可以建議在這種情況下的最佳做法,以減少擊中數據庫的次數?

回答

0

select_related()聯接在一個查詢所有這三種模式:

>>> from app.models import Task 
>>> task = Task.objects.all().select_related()[0] 
>>> task.project.job.job_number 
u'123' 
>>> from django.db import connection 
>>> len(connection.queries) 
1 
>>> connection.queries 
[{u'time': u'0.002', u'sql': u'QUERY = u\'SELECT "app_task"."id", "app_task"."project_id", "app_project"."id", "app_project"."job_id", "app_job"."job_number" FROM "app_task" INNER JOIN "app_project" ON ("app_task"."project_id" = "app_project"."id") INNER JOIN "app_job" ON ("app_project"."job_id" = "app_job"."job_number") LIMIT 1\' - PARAMS =()'}] 
>>> 

可讀SQL:

SELECT "app_task"."id", "app_task"."project_id", "app_project"."id", 
     "app_project"."job_id", "app_job"."job_number" 
FROM "app_task" 
INNER JOIN "app_project" ON ("app_task"."project_id" = "app_project"."id") 
INNER JOIN "app_job" ON ("app_project"."job_id" = "app_job"."job_number") 
+0

感謝您的回答。但是當我在shell中嘗試'len(connection.queries)'時,我得到了2,這意味着它已經擊中了DB兩次。任何想法? – killua8p

+0

'queries'列表包含當前會話期間執行的所有SQL smetements。可能你做了其他查找或對象創建?打印'connection.queries'列表以查看第二個SQL查詢。 – catavaran

+0

我檢查了'connection.queries'。 第一個查詢選擇任務表及其直接相關的表。第二個查詢選擇與與任務相關的項目相關的作業表。 – killua8p