详解Django的 distinct() 函数:对查询结果去重

  • Post category:Python

distinct() 是 Django ORM 中用于从查询结果中过滤重复值的方法。它可以应用于 QuerySet,并返回一个新的 QuerySet,其中每个结果都是独一无二的。

作用

distinct() 的主要作用是过滤重复的查询结果。它可以应用于 QuerySet 的任何字段,不仅仅是主键或唯一约束的字段。当您需要从一个查询结果集中取出独特的值时,通常就需要使用该方法。

使用方法

在 Django 中,要使用distinct(),只需在已经构建好的 QuerySet 对象后面添加该方法即可。例如:

from myapp.models import MyModel

# 获取查询结果集
result = MyModel.objects.filter(some_field='some_value')

# 筛选出不重复的结果集
unique_result = result.distinct()

在上述示例中,result 是一个普通的 QuerySet,该 QuerySet 由MyModel 模型中的某些字段过滤而成。然后使用 distinct() 方法来筛选不重复的结果集。注意,distinct() 会返回新的 QuerySet 对象。

实例

接下来看两个实际的示例,以便更好地理解distinct()的工作方式。

  1. 筛选用户收藏的不同书籍
from myapp.models import Book, BookMark

# 获取所有用户的书签 QuerySet
all_bookmarks = BookMark.objects.all()

# 获取所有用户收藏的书籍
all_books = Book.objects.filter(id__in=all_bookmarks.values('book_id'))

# 获取独特的书籍数组
unique_books = all_books.distinct()

在上述示例中,我们想找出所有用户收藏的书籍并返回一个不重复的 QuerySet。为了实现这个目标,我们需要首先获取所有用户的书签记录,并使用 values() 方法获取书签中的 book_id。接着,我们使用 filter() 方法,通过 id__in 条件过滤所有收藏的书籍。最后,使用 distinct() 方法过滤出不重复的书籍并返回一个新的 QuerySet 对象。

  1. 对象关联的多对多字段去重
from myapp.models import Person, Group

# 获取所有人群的 QuerySet
all_groups = Group.objects.all()

# 获取所有人参加的群
all_groups_for_users = Person.objects.filter(id__in=all_groups.values('members')).values_list('groups', flat=True)

# 筛选出不重复的结果
unique_groups = Group.objects.filter(id__in=all_groups_for_users).distinct()

在上述示例中,我们有两个模型类:PersonGroupPerson 模型有一个名为 groups 的多对多关联字段,用于存储参加的 Group 实例。现在,我们想从所有 Group 实例中获取所有与之关联的人群,并返回一个不重复的 QuerySet。为了实现这个目标,我们需要首先获取所有的群实例,然后获取所有人所参加过的群的 ID,并将其存储在 all_groups_for_users 变量中。接着,我们使用 filter() 方法来查找所有包含在 all_groups_for_users 列表中的群实例。最后,使用 distinct() 方法过滤出不重复的结果并返回一个新的 QuerySet 对象。

总之,distinct() 是 Django ORM 中非常有用的方法,它可以让我们从查询结果中去除重复的值并返回不重复的结果集。无论您是在编写 Web 应用程序、开发数据分析工具还是进行其他类型的工作,使用该方法可以让您更加轻松、高效地处理和操作查询结果。