Как исключить элементы с одинаковым полем, если поле даты больше, чем в других дубликатах? - PullRequest
0 голосов
/ 07 июля 2019

Итак, у меня есть модель комментариев и путем запроса

comments = Comments.objects.values('students_id', 'created_at')

Я получаю этот вывод

<QuerySet [
{'students_id': 4, 'created_at': datetime.date(2019, 6, 19)}, {'students_id': 2, 'created_at': datetime.date(2019, 6, 3)}, {'students_id': 1, 'created_at': datetime.date(2019, 6, 24)}, {'students_id': 6, 'created_at': datetime.date(2019, 6, 4)}, {'students_id': 6, 'created_at': datetime.date(2019, 6, 19)}, {'students_id': 5, 'created_at': datetime.date(2019, 6, 5)}, {'students_id': 4, 'created_at': datetime.date(2019, 7, 28)}, {'students_id': 6, 'created_at': datetime.date(2019, 6, 11)}]>

Это три комментария от студента с id = 6 и два комментария от студента с id = 4. Мне нужно получить только один последний комментарий от каждого студента. В этом примере это будет выглядеть так:

<QuerySet [
{'students_id': 2, 'created_at': datetime.date(2019, 6, 3)}, {'students_id': 1, 'created_at': datetime.date(2019, 6, 24)}, {'students_id': 6, 'created_at': datetime.date(2019, 6, 19)}, {'students_id': 5, 'created_at': datetime.date(2019, 6, 5)}, {'students_id': 4, 'created_at': datetime.date(2019, 7, 28)},]>

Заранее спасибо за ответ!

Ответы [ 3 ]

0 голосов
/ 07 июля 2019

используйте этот код:

queryset=Comments.objects.values('students_id', 'created_at').group_by('students_id').annotate(Latest_created_at=Max('created_at'))
queryset.delete()
0 голосов
/ 07 июля 2019

В сыром SQL это будет ... WHERE NOT EXISTS(SELECT * FROM Comments cc WHERE cc.student_id = c.student_id AND cc.created_at > c.created_at)

later_comments = Comments.objects.filter(student_id=OuterRef('student_id'), 
    created_at__gt=OuterRef('created_at'), ).values('created_at', )

latest_comments = Comments.objects.\
    annotate(has_later_comments=Exists(later_comments), ).\
    filter(has_later_comments=False, )

Если ваш created_at является столбцом Date (без времени), тогда вам нужно использовать => вместо >, потому что, возможно, в течение дня может быть создано более одного комментария. Таким образом, запрос будет содержать дополнительный предикат с дополнительным столбцом для упорядочения комментариев (например, id): WHERE cc.created_at > c.created_at OR cc.created_at = c.created_at AND cc.id > c.id

https://docs.djangoproject.com/en/2.2/ref/models/expressions/#exists-subqueries

0 голосов
/ 07 июля 2019

Вы можете использовать annotate и max, чтобы получить желаемый результат, подобный этому Comments.objects.values('students_id').annotate(Max('created_at')) и результат будет таким: <QuerySet [ {'students_id': 2, 'created_at__max': datetime.date(2019, 6, 3)}, {'students_id': 1, 'created_at__max': datetime.date(2019, 6, 24)},]>, в котором будут указаны Students_id и последний созданный_каталог. Чтобы использовать это, вы должны импортировать Макс из django.db.models, как это from django.db.models import Max

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