2010-11-21 58 views
0

的名單上有對象的列表:結合模型數據與對象

film_hc = [{'count': 2, 'pk': '33'}, 
      {'count': 1, 'pk': '37'}, 
      {'count': 1, 'pk': '49'}] 

的「PK」值模型中的一個記錄的主鍵。我想將該記錄的名稱字段添加到該對象列表中。爲了得到一個名字,我可以使用:

record = Film.objects.get(pk = film_hc[0]['pk']) 
record.name 

最後,我想有這樣的事情:

film_hc = [{'count': 2, 'pk': '33', 'name': 'name1'}, 
      {'count': 1, 'pk': '37', 'name': 'name2'}, 
      {'count': 1, 'pk': '49', 'name': 'name3'}] 

問:什麼是附加了必要的數據最有效的方法這個預先存在的列表?

我想我可以使用壓縮功能:

film_hc_with_names = zip(????, film_hc) 

的問題是我不知道我會在這些地方的替代????獲取對象,然後獲取列表中每個對象的名稱。我應該使用for循環嗎?什麼是最可取的選擇?

回答

1

爲避免多次觸擊數據庫,我建議您使用in_bulk queryset方法。這需要一個ID列表,並返回映射到模型實例的ID字典。所以你需要做的是首先運行你的字典列表來提取ID值,然後執行查詢,然後再次運行以獲取每個實例的名稱。儘管這是做了兩次額外的迭代,但它應該比運行多個數據庫查詢更快(儘管您應該始終確認)。

id_list = [film['id'] for film in film_hc] 
objects = Film.objects.only('name').in_bulk(id_list) 
for film in film_hc: 
    film['name'] = objects[film['id']].name 
+0

我肯定會在某個時間點找到in_bulk的用法。在這種情況下,我不知道迭代兩次是有意義的。似乎我們可以在一箇中做到。 – 2010-11-21 14:00:59

+0

@這是由你自己決定的,但是你不應該把注意力放在迭代上,因爲它是主要的低效率。多次單獨訪問數據庫效率低下得多。對我的代碼和aaronsterling的上面的代碼執行100次匹配的快速測試顯示,我的代碼爲0.370ms,而他的代碼爲0.542ms:所以我的方法效率大約提高了50%。 – 2010-11-21 16:07:38

+0

嗯。你是對的。測試它,這確實工作得更快。感謝您的跟進。 – 2010-11-21 17:18:26