第1步:
假设我有两个一对多的相关模型,例如:
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
name = models.CharField(max_length=300)
author = models.ForeignKey(Author)
pubdate = models.DateField()
如何获取所有作者的列表及其上一本书的名称(或者更确切地说是书籍对象本身)?
第2步:
我不确定这是解决方案的重大差异。
假设我现在拥有Book的BookBook子类(使用django-polymorphic),我想知道所有作者上一张PictureBook的picture_url(如果不是,也想知道是否为。)
from polymorphic import PolymorphicModel
class Book(PolymorphicModel):
name = models.CharField(max_length=300)
author = models.ForeignKey(Author)
pubdate = models.DateField()
class PictureBook(Book):
picture_url = models.CharField(max_length=200)
不幸的是,documentation about annotate中的示例仅显示直接的最小值/最大值。如果我从所有的PictureBook开始,那么我会想念那些没有PictureBook的作者。 This question与我有关系,但很老。我正在使用Django 1.7。
答案 0 :(得分:1)
在您的第一个示例中,如果关系设置如下:
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
books = models.ManyToMany(Book)
def latest_book(self):
"""
This is only efficient / accurate if you've prefetched books
in the right order!
"""
if self.books.exists():
return self.books.all()[0]
return None
class Book(models.Model):
name = models.CharField(max_length=300)
pubdate = models.DateField()
然后使用1.7中引入的Prefetch对象:
from django.db.models import Prefetch
authors = Author.objects.all().prefetch_related(
Prefetch('books', queryset=Books.objects.order_by('-pubdate')
for author in authors:
print author.latest_book()
2个数据库查询,但当然要知道您正在为每个作者加载每本书到内存中。也就是说,使用Prefetch对象的queryset arg,你可能会提高效率。
我让latest_book
成为作者的成员以保持示例代码的轻量级,但实际上您可能希望在作者模型的定义之外使用它,因为在这个特定的实现之外它没有用,并且调用了正确的预取。
我不熟悉django-polymorphic包,但我打赌你可以使用这种方法,因为预取也支持通用关系。