2016-03-09 20 views
1

当Entry对象数大于5000时,django有没有办法更有效地执行以下操作?如何在django中有效地使用_set.all()?

models.py

class Entry(models.Model): 
    user = models.TextField(db_column='User', blank=True) 
    date = models.DateTimeField(blank=True) 

class Color(models.Model): 
    color = models.TextField(blank=True) 
    entry = models.ForeignKey(Entry) 

而且让我们说,我希望得到所有的颜色为这些条目...

entrys = Entry.objects.all() 

for e in entrys: 
    print e.color_set.all() 

我希望能够给每一个对象涉及到一个特定的条目。例如,在这样的csv表中。

user, color 
john, blue 
john, orange 
bob, green 
bob, red 
bob, purple 

需要花费几秒钟时间查看我的所有条目。有没有更好的办法?

+1

你可以去周围的其他方式。获取所有Color对象,并通过'entry'对它们进行排序,然后进行迭代。 – AKS

+2

您可以根据[我刚刚提出的另一个问题的答案]使用'prefetch_related'(http://stackoverflow.com/a/35893764/1324033) – Sayse

+0

要扩展@Sayse评论,'selected_related'也可以作为选项。 https://docs.djangoproject.com/en/1.9/ref/models/querysets/#select-related你基本上想做一个急切的加载。 – themanatuf

回答

4

您应该使用prefetch_related

entrys = Entry.objects.all().prefetch_related('color_set') 

for e in entrys: 
    print e.color_set.all() 

而不是做的n,查询会做2,一个用于输入,以及一个外键查找

+0

这似乎没有跑得快......我错过了什么吗? –

+0

@JohnWaller - 我不确定,它可能是时间问题已不再在数据库端,但可能只是需要一段时间来打印出值或任何问题的csv部分是指 – Sayse

+0

@JohnWaller - 当然,你仍然试图从你的数据库中返回大量的记录,所以这里必须有一些时间 – Sayse

0

正如我在前面的评论,如果你只需要一个Entry的所有颜色在一起,你可以选择在entry所有Color对象,并命令他们:

colors = Color.objects.order_by('entry') 

现在,你可以遍历这些对象和打印出来你想要的方式:

for color in colors: 
    print(color.entry.user, color.color) 

# john, blue 
# john, orange 
# bob, green 

或者,您可以提取这些信息作为values_list

color_entries = list(colors.values_list('entry__user', 'color')) 
# [('john', 'blue'), ('john', 'orange'), ('bob', 'green'), ...] 
+0

如果我有另一个模型,也与入门有关,我也想要这些值? –

+1

这仍然会创建n(5000)个查询,因为它将在每次迭代中检索“入口”。 – Sayse

+0

但是,如果你使用'values_list',它会很有效率。或者,我是否错过了'values_list'的东西? – AKS