Полагаю, это будет работать:
Comment.objects.filter(*[
~Q(id__in=user.comments.order_by('-created')[3:].values_list('id', flat=True))
for user in User.objects.all()
])
Тем не менее, это не кажется ни питонским, ни эффективным способом решения проблемы. (Проблема эффективности может быть несколько решена с помощью кэша, но все же.)
Чего ты пытаешься достичь? Вы можете просто получить все комментарии пользователей и использовать только последние три. Предполагая, что ваши комментарии упорядочены по полю -created
:
{% for user in users %}
{% for comment in user.comments.all|slice:"3" %}{{ comment }}{% endfor %}
{% endfor %}
Срез будет преобразован в предложение LIMIT
в SQL-запросе, поэтому вы все равно не получите все комментарии. Конечно, для получения всех комментариев будет выполнено более одного запроса, поэтому использование кэширования шаблонов может помочь.
Опять же, это может не иметь смысла в вашем случае. Если этого не произойдет, было бы лучше, если бы вы уточнили требования.
Необработанный SQL
Если вы знаете, как делать то, что вы хотите, с необработанным SQL ([1] может помочь), то вам просто нужно найти способ как-то вставить его в extra()
([2] пример сложного дополнительного запроса, который может дать вам представление).
[1] Как выбрать ограниченное количество строк для каждого внешнего ключа?
[2] .extra django (где = предложения перекрываются переименованием таблицы .filter (foo__in = ... subselect