对查询集去重distinct(*fields)
2018-09-11 本文已影响148人
陆_志东
对查询集调用distinct,来实现对查询集的去重.
在sql中的体现就是使用了SELECT DISTINCT 语句
在默认的情况下,django查询集是不会默认去重的,像Blog.objects.all()这样的查询不会引入重复的行.只有在多表查询时会出现重复的行.这时候可以使用distinct()去重
注意
- 1.需要注意
distinct
和values
,会影响结果的唯一性,因为values
限制了比较的字段.默认全字段比较
同理distinct
设置字段参数,也将影响结果唯一性,因为distinct
设置字段参数后,将只比较设置的字段.默认是全字段比较.
举例:
上面的话的意思是如果一个模型有5
个字段,两条数据只有3
个字段是重复的,默认这两条数据是不重复的,因为还有两个字段不同.如果你使用values
或者distinct
指定了这3个重复的字段,那么这两条数据就会被认为是重复的.因为使用values
和distinct
之后会只比较这三个字段而不是全部字段,也就是影响了结果的唯一性 - 2.distinct和order by 一起使用时,需要注意下面两种情况
- distinct指定限制了去重的字段(非外键字段).这个时候你需要保证distinct设置的字段要和order by排序的字段保持一致,如果指定了多个字段,还要保证顺序一致.
示例:
Entry.objects.order_by('pub_date').distinct('pub_date')
- 如果distinct指定了外键字段.order by 需要和外键字段指向的模型使用的默认排序字段一致.django中任意模型如果指定排序方式,就会使用默认的id字段排序,如果元类设置定义了排序方法,就需要使用元类设置的排序方法
示例:
下面示例的前提是Entry通过外键字段blog关联了Blog模型类
没有设置排序的Blog模型类演示:
Entry.objects.order_by('blog__id').distinct('blog')
orEntry.objects.order_by('blog__pk').distinct('blog')
Blog模型设置了以自身的name字段排序演示:``Entry.objects.order_by('blog__name').distinct('blog')
- distinct指定限制了去重的字段(非外键字段).这个时候你需要保证distinct设置的字段要和order by排序的字段保持一致,如果指定了多个字段,还要保证顺序一致.