2013-11-06 3 views
0

Предполагая, что мои модели приведены ниже, как бы написать один запрос, который фильтрует производные данные о моделях? В этом примере я хотел бы потянуть «Все страницы в Times New Roman, которые являются частью книг с ровно десятью страницами и всеми страницами не Comic Sans». Нужно ли мне несколько запросов (фильтровать книги с этими атрибутами и использовать __in для второго фильтра) или денормализовать мою базу данных? В идеале эти модели могут стать довольно большими, и я хочу быстро найти эти производные количества, поэтому я считаю, что денормализация может быть моей лучшей ставкой.Django Queryset Construction

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

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

Я думаю, что вам не хватает отношения между двумя моделями –

ответ

0

Во-первых, я полагаю, что есть внешний ключ отношения между Page и Book как страницы принадлежат в книге.

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

Если вы не внесете изменения в базу данных, возможно, проще всего разбить это на два запроса. Первая часть - создать список книг, которые имеют 10 страниц и не имеют Comic Sans. Вы можете использовать reverse lookup по отношениям FK между Page и Book. Также вам понадобится annotate номера страниц.

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) 

Если это работает медленно, вы можете уменьшить объем обработки, затрачиваемое на просто дублируют данные в модели Книги, так что вы не считая страниц каждый раз, когда вы делаете запрос. Если в каждой книге есть только один шрифт, вы, вероятно, можете дублировать это в модели книги, чтобы сэкономить время.

Однако я бы рекомендовал сначала упростить его и оптимизировать только тогда, когда вам нужно, и он начинает замедляться. Возможно, есть лучший способ приблизиться к нему в зависимости от того, как он используется.