Django在预取相关后防止重复查询

时间:2016-11-29 11:41:37

标签: python django

我正在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调试工具栏,我最终得到了查询集中每本书的重复查询

enter image description here

阅读prefetch related的Django文档,其中有一节描述了我认为可能是罪魁祸首的行为

  

请记住,与QuerySets一样,任何暗示不同数据库查询的后续链接方法都将忽略以前缓存的结果,并使用新的数据库查询检索数据。

如何防止出现这些重复的查询?

0 个答案:

没有答案