timofeydeys
@timofeydeys
Свобода творцов

Как исключить повторяющиеся записи из QuerySet?

Всем привет! Собственно вопрос в шапке. Опишу проблему. Есть две модельки, коменты и рубрики. Коменты связаны контент-тайпом с рубриками, и MTPP сами с собой. Возникла потребность сортировать Querysey с рубриками, по дате создания последнего комментария в рубрике. Т.е. где последний комент был, та рубрика и выше должна быть. Сортировка делается просто, но получаются дубляжи из-за комментариев.
База PostgreSQL==9.6 Django==1.10

models.py Минимальные модельки
from mptt.models import MPTTModel, TreeForeignKey
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType

class Comment(MPTTModel):
    """ Content type framework """
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField("ID объекта")
    content_object = GenericForeignKey('content_type', 'object_id')

    """ MTPP Tree comments """
    parent = TreeForeignKey('self', null=True, blank=False, related_name='children', db_index=True, verbose_name="Родительский комментарий")

    date_create = models.DateTimeField("Дата создания", auto_now_add=True)


class Discussion(ImageFieldAbstract):
    """ Item discussion """
    date_create = models.DateTimeField("Дата создания", auto_now_add=True)
    comments = GenericRelation(Comment)


Пытаюсь отсортировать:
from django.db.models import DateTimeField, Case, When
import datetime

Discussion.objects.all().annotate(
    comment_old_date=Case(
        When(
            comments__date_create__isnll=True,
            then=datetime.datetime.strptime('1950-01-01 00:00:00', '%Y-%m-%d %H:%M:%S')
        ),
        default='comments__date_create',
        output_field=DateTimeField()
    )
).order_by('-comment_old_date').distinct()


В результате distinct не отрабатывает. И понятно почему. Потому что если не указать поля, то он идет по каждому столбцу в результирующей таблице и сверяет на уникальность(а order_by добавляет поля в select для сортировки, и поле с датой уникальное у всех получается.)

Пробовал уже всяко:
.order_by('pk', '-comment_old_date').distinct('comment_old_date', 'pk')
.order_by('pk', '-comment_old_date').distinct('pk', 'comment_old_date')
.distinct('pk', 'comment_old_date').order_by('pk', '-comment_old_date')
.distinct().order_by('pk', '-comment_old_date')
# И Т,Д,


Подскажите, как правильно реализовать это? Или поправьте меня где я не прав.
  • Вопрос задан
  • 1217 просмотров
Пригласить эксперта
Ответы на вопрос 2
timofeydeys
@timofeydeys Автор вопроса
Свобода творцов
Вопрос снят. В итоге сделал так.
Discussion.objects.all().annotate(
                comment_old_date=Max(
                    Case(
                        When(
                            comments__date_create__isnull=True,
                            then=datetime.datetime.strptime('1950-01-01 00:00:00', '%Y-%m-%d %H:%M:%S')
                        ),
                        default='comments__date_create'
                    )
                )
            ).order_by('-comment_old_date')
Ответ написан
Комментировать
@jagrmi
beginner python developer
есть еще в той же теме где filter еще одна фича, она убирает все повторяющие записи
distinct() - если интересно загугли про его, как-то использовал помню, но эта "функция" не работает с MySQL
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы