2013-08-22 25 views
1

我有两个非常简单的模型:Django的 - 检查模型有孩子(相关型号)

class Author(models.Model): 
    name = models.CharField(max_length=255) 

    def hasBooks(self): 
     return self.books.count() 

class Book(models.Model): 
    title = models.ForeignKey(Author, related_name="books") 

我想编写一个函数hasBooks(如上图所示),仅仅返回true或false如果作者有相关书籍。我认为这样做的唯一方法是获取count(),如果它大于0则返回true,如果为0则返回false。与此相关的问题是书本的表是巨大的,有些作者有数以千计的书籍,因此处理浪费的数量才能获得确切的。我只想知道如果有一个人在那里。

有没有办法做到这一点使用较少的处理?

回答

1

你可以尝试获得的第一个元素:

def hasBooks(self): 
    return len(self.books.all()[:1]) == 1 

可以肯定这会注意到检索所有的元素,但只有一个演员的第一本书(切片意味着LIMIT 1中的SQL查询)。

您也可以使用有用exists()函数:

def hasBooks(self): 
    return self.books.exists() 
+0

我打算这样做,我只是不确定是否有办法做到这一点,而没有检索书的价值。 –

+0

你试过了存在的功能吗? – Julio

+0

这就像一个魅力,谢谢你! –

0

为什么不能两者兼而有之? :)

def has_books(self): 
    return self.books.count() or False 

Python的评估0(或[],或{}None,对于这个问题)为False。因此,当计数返回0时,逻辑表达式的计算结果为0False = False - 这恰好就是您希望代码执行的操作!整洁的部分是,当count非零时,函数仍然会返回一个整数!

如下你或许可以用它在你的代码:

a = Author.objects.get(pk=1827) 
if not a.has_books(): 
    num_books = a.has_books() 

的优点(在我看来)是你得到更多的是出于同样的分贝的呼叫,并有可能挽救自己不必要的额外调用到数据库。

+0

这对于不同情况很有用,但问题在于作者和书籍的数量。我不想让数据库浪费时间“计数”,因为我实际上并不需要计数。我真正需要知道的是,如果没有任何东西,就像Julio上面指出的那样,exists()的效果非常好!虽然谢谢! –

+0

够公平的!我的工作假设你需要两个 - 作者是否有任何书籍以及作者的书籍数量。如果你只需要检查前者,那么是的,.exists()是一个更好的选择。 :) –