我正在Django开展一个相当简单的图书馆项目,这是我的模型,一本书可以有很多副本,每个副本可以有很多贷款。
class Author(models.Model):
name = models.CharField(max_length=200, unique=True)
class Book(TimeStampedModel):
isbn = models.CharField(max_length=13, primary_key=True)
title = models.CharField(max_length=200, db_index=True, unique=True)
authors = models.ManyToManyField('Author', related_name='books')
@property
def is_available(self):
"""Returns True if the Book has any available copies"""
return self.copies.exclude(loans__returned=False).exists()
class BookCopy(models.Model):
book = models.ForeignKey('Book', related_name='copies')
class Loan(models.Model):
start_date = models.DateField()
end_date = models.DateField()
returned = models.BooleanField(default=False)
customer = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True,
null=True, related_name='loans')
book_copy = models.ForeignKey(
'BookCopy', on_delete=models.CASCADE, related_name='loans')
我有一个包含书籍列表的相当简单的视图
def book_list(request):
book_list = Book.objects.prefetch_related('authors', 'copies__loans')
return render(request, 'books/book_list.html', {'books': books})
为了确定一本书是否可用,我在Book模型中写了属性is_available
。但是,当我在模板中使用以下内容调用此属性时:
{% for book in books %}
{% if not book.is_available %}
-- Template stuff --
{% endif %}
{% endfor %}
根据Django调试工具栏,我最终得到了查询集中每本书的重复查询
阅读prefetch related的Django文档,其中有一节描述了我认为可能是罪魁祸首的行为
请记住,与QuerySets一样,任何暗示不同数据库查询的后续链接方法都将忽略以前缓存的结果,并使用新的数据库查询检索数据。
如何防止出现这些重复的查询?