Одним из подходов может быть использование Subquery
выражений, как задокументировано здесь .
Предположим, ваша модель SampleData выглядит следующим образом:
class SampleData(models.Model):
id2 = models.IntegerField()
value = models.IntegerField()
timestamp = models.DateTimeField()
(я заменил id на id2, чтобы избежать конфликтов с идентификатором модели).
Затем вы можете удалить свои дубликаты следующим образом:
newest = SampleData.objects.filter(id2=OuterRef('id2'), value=OuterRef('value')).order_by('-timestamp')
SampleData.objects.annotate(newest_id=Subquery(newest.values('pk')[:1])).exclude(pk=F('newest_id')).delete()
Редактировать:
Кажется, что MySQL имеет некоторые проблемы, связанные с удалением и подзапросами, как описано в этом SO сообщении.
В этом случае должен помочь двухэтапный подход: сначала получить идентификаторы удаляемых объектов, а затем удалить их:
newest = SampleData.objects.filter(id2=OuterRef('id2'), value=OuterRef('value')).order_by('-timestamp')
ids2delete = list(SampleData.objects.annotate(newest_id=Subquery(newest.values('pk')[:1])).exclude(pk=F('newest_id')).values_list('pk', flat=True))
SampleData.objects.filter(pk__in=ids2delete).delete()