从 Django 查询集中删除具有重复值的 objects

Remove objects with duplicated values from Django queryset

我想从查询集中删除具有相同字段值的 objects。我在这里看到了一些相关的答案,但是 none 其中使用了 annotate 和 Min 功能,我不知道这种方法是否可行。

假设我有一个 'Book' 模型和 'Library' 模型 FK。一个图书馆可以有多本同名的书。

我怎样才能从该图书馆获得不同书名和较低价格的图书清单?

我尝试了不同的方法但没有成功:

models.py

class Library(models.Model):
    name = models.CharField(_('Library name'), max_length=255)
    location = models.ForeignKey(Location, on_delete=models.CASCADE)

class Book(models.Model):
    name = models.CharField(_('Title'), max_length=255)
    author = models.CharField(_('Author'), max_length=255)
    editorial = models.CharField(_('Editorial'), max_length=255)
    price = models.FloatField(_('Price'), default=0)
    library = models.ForeignKey(Library, on_delete=models.CASCADE, related_name='libraries',
                                related_query_name='libraries')

查询集

Book.objects.annotate(count_id=Count('title'), min_price=Min('price')).filter(library__id=21, price=F('min_price')).values_list('title')

示例:

有了这个objects |编号 |标题 |价格 | |:---- |:------:| :-----| | 1 |猜火车 | 3 | | 2 |麦田里的守望者 | 2 | | 3 |猜火车 | 1 | | 4 |指环王 | 5 | | 5 |猜火车 | 5 |

我想获取以下查询集:

ID Title Price
2 The Catcher in the rye 2
3 Trainspotting 1
4 Lord of the Rings 5

编辑:

在 Count 中使用 distinct=True 得到以下结果:

在这种情况下,我的图书馆包含两本价格相同的 Trainspotting 书籍和 'The Catcher in the Rye' 的两本书,价格分别为 2 和 4。

我在这里打印名称中带注释的字段以查看可能有什么问题:Book.objects.annotate(count_id=Count('title', distinct=True), min_price=Min('price')).filter(library__id=21, price=F('min_price')).values_list('name', 'min_price', 'count_id')

我获得的QS如下:

<QuerySet [('Trainspotting', 1.0, 1), ('Trainspotting', 1.0, 1), ('The Catcher in the Rye', 2.0, 1), ('The Catcher in the Rye', 4.0, 1)]>

非常感谢您的帮助!

你可以这样做:

Book.objects.values('title').annotate(count=Count('title'), price=Min('price'))

这将 return 您计算每本书的标题数,以及每本书的最低价格。

需要注意annotatevalues的顺序。您可以在这里阅读详细说明:https://docs.djangoproject.com/en/3.2/topics/db/aggregation/#order-of-annotate-and-values-clauses