我想弄清楚如何在没有运气的情况下解决这个问题。情况是作者有很多书籍按类型划分,我希望在查询作者时它会返回作者和书籍对象除以流派。
Author object would have these properties:
name
fantasy - would have one book based by given date
crime - would have one book based by given date
romance - would have one book based by given date
通过不在作者模型中制作成千上万的外键(如果我将拥有那么多类型),有没有一种理智的方法来实现这一点?
class Author(models.Model):
name = models.CharField(u'Name',max_length=100)
GENRE = (
(0,u'Fantasy'),
(1,u'Crime'),
(2,u'Romance')
)
class Book(models.Model):
author = models.ForeignKey(Author)
name = models.CharField(u'Name',max_length=100)
genre = models.SmallIntegerField(u'Genre',choices=GENRE)
date = models.DateField(u'Publish date')
经过仔细检查后,sgarza62的例子似乎与大量数据有关。 所以我尝试了新的django 1.7功能Prefetch
authors = Author.objects.all().prefetch_related(
Prefetch("book", queryset=Book.objects.filter(genre=0,date_from__lte=datetime.datetime.now()), to_attr='x_fantasy'),
Prefetch("book", queryset=Book.objects.filter(genre=1,date_from__lte=datetime.datetime.now()), to_attr='x_crime'),
Prefetch("book", queryset=Book.objects.filter(genre=2,date_from__lte=datetime.datetime.now()), to_attr='x_romance')
)
但我有2个问题,如何预取一个对象(本例中的最新书),第二个,如何根据预取值进行排序。
答案 0 :(得分:2)
如果您要查询所有或多位作者,我建议 prefetching related fields 。这将在一次点击中抢夺所有相关对象到数据库,并将对象存储在Queryset中。
authors = Author.objects.all().prefetch_related('book_set')
for author in authors:
# accessing related field will not cause a hit to the db,
# because values are cached in Queryset
for book in author.books_set:
print book.genre
如果您只是查询一位作者,那么这不是什么大问题。
author = Author.objects.get(pk=1)
her_books = author.book_set
for book in her_books:
print book.genre
修改强>
我很难理解你将要做的事情。但是,如果您正在为某位作者寻找每种类型的最新书籍:
author = Author.objects.get(pk=1)
author_books = author.book_set.order_by('-date') # most recent, first
author_genres = set([b.genre for b in author_books])
for g in author_genres:
print next((b for b in author_books if b.genre==g), None)
请记住,这些操作都在Queryset上,并且每次都没有访问数据库。这很好,因为查询数据库是一项昂贵的操作,并且大多数作者都有相对较小的作品列表,因此查询集通常很小。