Django подзапрос externalref ('id') Возможно, вам понадобится добавить явные приведения типов - PullRequest
0 голосов
/ 04 марта 2020

Я использую postgresql. я пишу подзапрос в подзапрос я хочу применить фильтр на id родительской таблицы с полем дочерней таблицы. но он показывает ошибку

запрос: orders = Order.objects.filter(user=request.user, status='P') albums = models.Album.objects.annotate(purchased_status=Subquery(orders.values('id').filter(item_id=OuterRef('id'))[:1]))

Ошибка django.db.utils.ProgrammingError: operator does not exist: character varying = integer LINE 1: ...atus" = 'P' AND U0."user_id" = 1 AND U0."item_id" = "bookcen... HINT: No operator matches the given name and argument types. You might need to add explicit type casts.

, если я применяю фильтр к любому из полей, отличных от идентификатора, он работает нормально. это исправление ошибки, если я добавлю id для родительской таблицы как foreign key в дочерней таблице, но не хочу этого делать.

выдается, если из-за того, что OuterRef('id') возвращает ссылочный идентификатор, а не просто целочисленное значение, подобное 1 или 2 есть ли способ, с помощью которого OuterRef('id') может вернуть целочисленное значение id.

1 Ответ

0 голосов
/ 04 марта 2020

docs читать:

Использовать OuterRef, когда набор запросов в подзапросе должен ссылаться на поле из внешнего запроса.

соответствующий пример :

newest = Comment.objects.filter(post=OuterRef('pk')).order_by('-created_at')
Post.objects.annotate(newest_commenter_email=Subquery(newest.values('email')[:1]))

Это модель Comment, которая имеет ForeignKey для модели Post, а newest собирает все Comments, связанные с каждым Post, и сортирует их от самых последних к самым старым.

Из этого Subquery выбирается столбец email, и первая строка извлекается в атрибут newest_commenter для каждого Post в запросе.

Следовательно, в вашем примере, предполагая, что Order имеет ForeignKey для Album, вы можете сделать что-то вроде:

orders = Order.objects.filter(album=OuterRef('pk'), user=request.user, status='P')
models.Album.objects.annotate(purchased_status=Subquery(orders.values('id')[:1]))

Таким образом, для каждого Album вы получите атрибут purchased_status, который будет содержать id первого Order, если текущий пользователь сделал хотя бы один Order со статусом P.

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