Как отфильтровать только строки, содержащие первое вхождение элемента в запросе Django

У меня есть следующие данные из моей модели Django

id  Date  value
0   1975     a
21  1975     b
1   1976     b
22  1976     c
3   1977     a
2   1977     b
4   1978     c
25  1978     d
5   1979     e
26  1979     f
6   1980     a
27  1980     f

Модель

class Items(models.Model):
    date = models.DateField()
    value = models.CharField()

У меня проблемы с поиском способа сохранить только строки, содержащие первое вхождение "значения". Я хочу отбросить дублирующиеся "значения", сохранив строку с наименьшей "датой".Конечный результат должен быть:

id   Date value
0   1975     a
21  1975     b
22  1976     c
25  1978     d
5   1979     e
26  1979     f

Вы можете отфильтровать, исключив все элементы, для которых существует более ранняя запись:

from django.db.models import Exists, OuterRef

Items.objects.filter(
    ~Exists(Items.objects.filter(
        Q(date__lt=OuterRef('date')) | Q(Date=OuterRef('date'), pk__lt=OuterRef('pk')),
        value=OuterRef('value')
    ))
)

Таким образом, мы проверяем, существует ли запись с тем же value, где date меньше, чем наша текущая запись, или где дата та же, но первичный ключ меньше (как tie breaker).


Примечание: обычно модели Django присваивается сингулярное имя, поэтому Items вместо Item.

Вернуться на верх