0

假设我的模型如下,我将如何编写一个查询来过滤关于模型的派生数据?在此示例中,我想提取“Times New Roman 中的所有页面,这些页面是恰好十页的书籍的一部分,并且所有页面都不在 Comic Sans 中”。我是否需要多个查询(过滤具有这些属性的书籍并使用 __in 作为第二个过滤器)或非规范化我的数据库?理想情况下,这些模型可能会变得很大,我希望快速查找这些派生量,所以我认为非规范化可能是我最好的选择。

class Book(models.Model):
    author = models.CharField()

class Page(models.Model):
    number = models.IntegerField()
    font = models.Charfield()
    book = models.ForeignKey(Book)
4

1 回答 1

0

首先,我假设PageBook作为一本书的页面之间存在外键关系。

class Page(models.Model):
    book = models.ForeignKey(Book)
    number = models.IntegerField()
    font = models.Charfield()

在不显着修改数据库的情况下,将其分解为两个查询可能是最简单的。第一部分是生成一个有 10 页且没有 Comic Sans 的书籍列表。您可以对和之间的 FK 关系使用反向查找。您还需要注释页码。PageBook

book_list = Book.objects.exclude(page__font="Comic Sans").annotate(page_count=Count('page')).filter(page_count=10)

查询的最后一部分相当简单。

page_query_set = Page.objects.filter(font="Times New Roman").filter(book__in=book_list)

如果这运行缓慢,您可以通过在 Books 模型中复制数据来减少处理量,这样您就不必在每次进行查询时计算页数。如果每本书只有一种字体,您可能也可以在书本模型中复制它以节省时间。

但是,我建议首先保持简单,仅在需要时才进行优化,并且它开始变慢。可能有更好的方法来处理它,具体取决于它的使用方式。

于 2013-11-06T20:37:53.063 回答