2011-09-12 97 views
1

我是新来的Django,我觉得这是一个简单的问题 -Django的过滤器返回多个值

我有编码如下一个中间类 -

class Link_Book_Course(models.Model): 
    book = models.ForeignKey(Book) 
    course = models.ForeignKey(Course) 
    image = models.CharField(max_length = 200, null=True) 
    rating = models.CharField(max_length = 200,null=True) 
    def __unicode__(self): 
     return self.title 
    def save(self): 
     self.date_created = datetime.now() 
     super(Link_Book_Course,self).save() 

我在做这个打电话,因为我想必须有所有的书籍的作者(书是一种模型,笔者作为一名CharField)

storeOfAuthorNames = Link_Book_Course.objects.filter(book__author) 

但是,它不会返回所有作者的一个QuerySet,实际上,它会抛出一个错误。

我认为这是因为book__author有多个值 - 我怎么能得到所有这些值?

谢谢!

+0

要查询给定书籍的所有作者或者Link_Book_Course中提及的至少一本书的所有作者吗? – ftartaggia

回答

0

你试图使用过滤器的方法转化或多或少成这样的SQL:

SELECT * FROM Link_Book_Course INNER JOIN书(...),其中Book.author =;

所以当你看到你的查询有一个不完整的where子句。

无论如何,这不是你正在寻找的查询。

的东西像什么(假设作者是本书的一个简单的文本字段,你想从Link_Book_Course情况仅指书的作者):

Book.objects.filter(pk__in = Link_Book_Course.objects.all() .values_list(“book”,flat = True))。values_list(“author”,flat = True)

+0

我不会推荐一个使用这样的查询,它非常不高效。 –

+0

正确。任何建议? – ftartaggia

+0

哦,是的,nrabinowitz的回答得到了重点! – ftartaggia

0

首先,过滤器语句过滤匹配某个模式的字段。所以如果Book有一个简单的ForeignKey作者,你可以有
storeOfAuthorNames = Link_Book_Course.objects.filter(book__author="Stephen King"),但不只是
storeOfAuthorNames = Link_Book_Course.objects.filter(book__author)

一旦你过去,我猜书有作者为ManyToManyField,不是ForeignKey(因为一本书可以有多个作者,一个作者可以发布多书吗?)在这种情况下,只是filter(book__author="Stephen King")意愿依然不足够。尝试Link_Book_Course.objects.filter(book_author__in=myBookObject.author.all())

3

我不认为你正在使用正确的queryset方法。 filter()过滤器通过它的参数 - 这样的预期的用法是:

poe = Author.objects.get(name='Edgar Allen Poe') 
course_books_by_poe = Link_Book_Course.objects.filter(book__author=poe) 

它看起来像你想拉的名单在特定过程中使用的所有书籍的作者(或者所有课程?) 。也许你正在寻找.values()values_list()

all_authors_in_courses = Link_Book_Course.objects.values_list(
     'book__author', flat=True 
    ).distinct() 

编辑:每@ ftartaggia的建议更新)

+0

如何在最后一条语句中添加一个distinct(),如果方便的话,使用values_list('book_author',flat = True)如何? – ftartaggia

+0

@ftartaggia - 两个很好的建议,现在包括在内。 – nrabinowitz

1

正如其他人已经解释的,使用过滤器的方法是让全组对象的一个​​子集,不返回其他实例模型(无论相关的对象或左右)

如果你想有作者模型的实例从Django的ORM回来,你可以使用聚合的API,那么你可能需要做这样的事情:

from django.db.models import Count 
Author.objects.annotate(num_books=Count('book')).filter(num_books__gt=1)