当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Python Django QuerySet.distinct用法及代码示例


本文介绍 django.db.models.query.QuerySet.distinct 的用法。

声明

distinct(*fields)

返回在其 SQL 查询中使用 SELECT DISTINCT 的新 QuerySet。这消除了查询结果中的重复行。

默认情况下,QuerySet 不会消除重复行。实际上,这很少会成为问题,因为像 Blog.objects.all() 这样的简单查询不会引入重复结果行的可能性。但是,如果您的查询跨越多个表,则在评估 QuerySet 时可能会得到重复的结果。那时你会使用 distinct()

注意

order_by() 调用中使用的任何字段都包含在 SQL SELECT 列中。当与 distinct() 结合使用时,这有时会导致意外结果。如果您按相关模型中的字段排序,这些字段将添加到选定的列中,否则它们可能会使重复的行看起来不同。由于额外的列不会出现在返回的结果中(它们只是为了支持排序),因此有时看起来返回的结果不明确。

同样,如果您使用 values() 查询来限制选定的列,则任何 order_by() (或默认模型排序)中使用的列仍将涉及并可能影响结果的唯一性。

这里的寓意是,如果您使用distinct(),请注意按相关模型排序。同样,当同时使用distinct() values() 时,按不在 values() 调用中的字段排序时要小心。

仅在 PostgreSQL 上,您可以传递位置参数 ( *fields ) 以指定应应用 DISTINCT 的字段名称。这将转换为 SELECT DISTINCT ON SQL 查询。这就是区别。对于正常的distinct() 调用,数据库在确定哪些行不同时比较每一行中的each 字段。对于具有指定字段名称的distinct() 调用,数据库将仅比较指定的字段名称。

注意

指定字段名称时,mustQuerySet 中提供 order_by(),并且 order_by() 中的字段必须以 distinct() 中的字段开头,顺序相同。

例如,SELECT DISTINCT ON (a) 为您提供 a 列中每个值的第一行。如果你不指定一个顺序,你会得到一些任意的行。

示例(第一个之后的仅适用于 PostgreSQL):

>>> Author.objects.distinct()
[...]

>>> Entry.objects.order_by('pub_date').distinct('pub_date')
[...]

>>> Entry.objects.order_by('blog').distinct('blog')
[...]

>>> Entry.objects.order_by('author', 'pub_date').distinct('author', 'pub_date')
[...]

>>> Entry.objects.order_by('blog__name', 'mod_date').distinct('blog__name', 'mod_date')
[...]

>>> Entry.objects.order_by('author', 'pub_date').distinct('author')
[...]

注意

请记住, order_by() 使用已定义的任何默认相关模型排序。您可能必须按关系 _id 或引用字段显式排序,以确保 DISTINCT ON 表达式与 ORDER BY 子句开头的表达式匹配。例如,如果 Blog 模型通过 name 定义了 ordering

Entry.objects.order_by('blog').distinct('blog')

…不起作用,因为查询将按 blog__name 排序,因此与 DISTINCT ON 表达式不匹配。您必须按关系 _id 字段(在本例中为 blog_id)或引用的字段(blog__pk)显式排序,以确保两个表达式匹配。

相关用法


注:本文由纯净天空筛选整理自djangoproject.com大神的英文原创作品 django.db.models.query.QuerySet.distinct。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。