基于Django上的列检索不同的记录

时间:2011-01-18 10:53:37

标签: django distinct

我需要检索下表的记录列表,其中包含与名称相关的不同值:

Class C:

name                value
A ------------------ 10
A ------------------ 20
A ------------------ 20
B ------------------ 50
C ------------------ 20
D ------------------ 10
B ------------------ 10
A ------------------ 30

我需要删除name的所有重复值,并且只显示以下内容:

name                value
A ------------------ 30
B ------------------ 10
C ------------------ 20
D ------------------ 10

正如您所看到的,它几乎看起来像一个python集。我可以使用Python生成集合,但我想知道Django的ORM是否具有此功能。

我尝试使用distinct,但它不接受任何参数来指定哪个列必须具有不同的值。知道如何让这个查询工作吗?

5 个答案:

答案 0 :(得分:19)

.distinct()是工具,但这是我必须使用的语法:

Model.objects.values_list('name', flat=True).distinct()

这样你只能得到一个值列表[A,B,C,D],而不是它们的对象。

答案 1 :(得分:0)

你也可以使用raw:

queryraw = C.objects.raw('SELECT name, value FROM prj_c GROUP BY name')

或添加ORDER BY以使任何组具有更高的值:

queryraw = C.objects.raw('SELECT name, value FROM prj_c GROUP BY name ORDER BY value')

在任何情况下,您都可以拥有list()个对象。

此处有用的文档:https://docs.djangoproject.com/en/2.0/topics/db/sql/

答案 2 :(得分:0)

sqlite与众不同的问题是它在所有返回值上都是不同的。要区分一个列名,例如:'url'可以从表中获取所有唯一的url,但还可以获取其余数据,请使用子查询。

子查询获取URL的ID,然后使用该ID对这些想法进行另一个查询。当然,这没有常规的快。

link_ids = (
    Resources
    .values('url')
    .distinct()
    .annotate(
        occurrences=Count('url'),  # make unique 'urls' only occur once.
        pk=Min('pk')  # return pk of first occurrence
    )
)
broken_links_qs = (
    Resources.filter(id__in=Subquery(link_ids.values('pk')))
)

(在给出先前答案的时候,django还没有子查询功能。)

答案 3 :(得分:0)

这不是超级优雅,但是可以完成大约一行工作:

# Fetch all rows to limit num of queries
all_rows = MyModel.objects.all()

# Query against the full list to return a list of objects
item_list = [all_rows.filter(myfield=item['myfield']).last() for item in MyModel.objects.values('myfield').distinct()]

这将为您执行DISTINCT的每个值检索完整的模型实例。一些用例可能需要不同的过滤。

然后只需在name上的每个项目中使用valueitem_list属性即可获取不同的数据。

答案 4 :(得分:0)

使用以下语法应该可以解决您的问题。 values('name','value')。distinct()