2013-05-30 120 views
1

假设我有两个相关的模型Django的 - 使用相关模型领域的表现

class Foo(models.Model): 
    value = models.FloatField() 

class Bar(models.Model): 
    multiplier = models.FloatField() 
    foo = models.ForeignKey(Foo, related_name="bars") 

    def multiply(self): 
     return self.foo.value * self.multiplier 

美孚的实例会经常有酒吧的许多情况,但有些信息是有关该酒吧确实被存储在计算在富(因为它是与酒吧的所有实例相同)

问题是,当我做这样的事情:

foo = Foo.objects.latest() 
[x.multiply() for x in foo.bars.all()] 

它结束了击球数据库很多,因为foo.bars.all()中的每个Bar对象都会在数据库中查询Foo对象。所以,如果我有10个酒吧,那么我会产生11个数据库查询(1个获得10个酒吧的查询集,每个酒吧对象返回1以获得self.foo.value)。使用select_related()似乎没有帮助。

我的问题是: 1)我正确地认为memcached(例如Johnny Cache,Cache Machine)会解决这个问题吗? 2)有没有一种设计对象关系的方法,可以在没有缓存的情况下使命令更高效?

+0

为什么会出现11个查询?这将只是2个查询。 – karthikr

+0

对不起,这是一个错字,应该是[x.multiply()for x in foo.bars.all()]。因为multiply()需要一个存储在foo中的值,所以multiply()的每次调用都必须检索foo。 – hgcrpd

回答

3

正是这种情况下,select_relatedprefetch_related被创建。当您使用这些查询时,Django的ORM将采用以下两种技术之一来避免多余的数据库请求:通过JOIN(select_related)关联关系或在其QuerySets中预先缓存一对多/多对多关系。

# Hits the database 
foo = Foo.objects.prefetch_related('bars').latest() 

# Doesn't hit the database 
[x.value for x in foo.bars.all()] 
+0

prefetch_related()是它。谢谢! – hgcrpd