Python / Django - Как аннотировать QuerySet значением, определенным другим запросом - PullRequest
0 голосов
/ 17 ноября 2018

Django 1.11, python 2.7, postgresql

У меня есть набор моделей, которые выглядят так:

class Book(Model):
    released_at=DateTimeField()

class BookPrice(Model):
    price = DecimalField()
    created_at = DateTimeField()

Предполагая наличие нескольких записей для Book и BookPrice (созданных в разные моменты времени), я хочу получить набор запросов Book с аннотацией со значением BookPrice.price, которое действовало на момент выпуска Книги. Что-то вроде:

books = Book.objects.annotate(
            old_price=Subquery(BookPrice.objects.filter(
                          created_at__lt=OuterRef('released_at')
                          )
                          .order_by('created_at')
                          .last()
                          .price
                      )
           ) 

Когда я пытаюсь что-то подобное, я получаю сообщение об ошибке: This queryset contains a reference to an outer query and may only be used in a subquery.

Я мог бы достаточно легко получить данные с помощью цикла for, но я пытаюсь подготовить большой кусок данных для загрузки в формате CSV, и я не хочу перебирать каждую книгу, если смогу помочь.

1 Ответ

0 голосов
/ 17 ноября 2018

Ваша проблема в том, что вы делаете .last().price.Этот код разрешает (выполняет) запрос и пытается получить объект Python.Следовательно, ошибка, которую вы получаете, поскольку запрос, который вы пытаетесь выполнить, содержит OuterRef, поэтому он не может быть выполнен.

Вы должны преобразовать свой запрос в нечто вроде следующего:

last_price_before_release_query = BookPrice.objects.filter(created_at__lt=OuterRef('released_at')).order_by('-created_at').values('price') # Note the reversed ordering 
books = Book.objects.annotate(old_price=Subquery(last_price_before_release_query[:1]))

Вы можете получить больше информации здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...