简体   繁体   English

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

[英]Remove objects with duplicated values from Django queryset

I want to remove objects with the same field value from a queryset.我想从查询集中删除具有相同字段值的对象。 I've seen some related answers here, but none of them use the annotate and Min feature and I don't know if that approach is even possible.我在这里看到了一些相关的答案,但他们都没有使用 annotate 和 Min 功能,我不知道这种方法是否可行。

Imagine I have a 'Book' model with a 'Library' model FK.想象一下,我有一个带有“图书馆”模型 FK 的“书籍”模型。 A Library could have multiple Books with the same title.一个图书馆可以有多本同名书籍。

How can I obtain a list of Books from that Library with different titles and lower price?如何从该图书馆获得不同标题和更低价格的图书列表?

I've tried different approaches with no success:我尝试了不同的方法但没有成功:

models.py模型.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')

Queryset查询集

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

Example:例子:

Having this objects |有这个对象| ID |身份证 | Title |标题 | Price |价格 | |:---- |:------:| |:---- |:------:| :-----| :----| | | 1 | 1 | Trainspotting |猜火车 | 3 | 3 | | | 2 | 2 | The Catcher in the rye |麦田里的守望者 | 2 | 2 | | | 3 | 3 | Trainspotting |猜火车 | 1 | 1 | | | 4 | 4 | Lord of the Rings |指环王 | 5 | 5 | | | 5 | 5 | Trainspotting |猜火车 | 5 | 5 |

I want to obtain the following queryset:我想获得以下查询集:

ID ID Title标题 Price价钱
2 2 The Catcher in the rye麦田里的守望者 2 2
3 3 Trainspotting猜火车 1 1
4 4 Lord of the Rings指环王 5 5

EDIT:编辑:

Using the distinct=True in Count gives me the following results:在 Count 中使用distinct=True得到以下结果:

In this case my Library contains two Trainspotting books with the same price and two titles of 'The Catcher in the Rye' with prices 2 and 4.在这种情况下,我的图书馆包含两本价格相同的猜火车书和两本价格为 2 和 4 的“麦田里的守望者”。

Here I'm printing the annotated fields within the name to see what's could be wrong: 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')在这里,我正在打印名称中带注释的字段以查看可能有什么问题: 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')

The QS I obtain is the following:我获得的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)]>

Thanks you very much for your help!非常感谢您的帮助!

You can do:你可以做:

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

This will return you the count of titles per title, and also the minimum price per title.这将返回每个标题的标题计数,以及每个标题的最低价格。

You need to pay attention to the order of annotate and values .您需要注意annotatevalues的顺序。 You can have a read here for a detailed explanation: https://docs.djangoproject.com/en/3.2/topics/db/aggregation/#order-of-annotate-and-values-clauses您可以在此处阅读详细说明: https : //docs.djangoproject.com/en/3.2/topics/db/aggregation/#order-of-annotate-and-values-clauses

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM