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

  • Post category:Python

Django中的distinct()函数可以用于去重查询结果。具体来说,它可以通过指定需要去重的字段,将查询结果中重复的数据去除。以下是distinct()函数的使用方法和示例。

使用方法

distinct()函数有两种使用方式,一种是调用模型管理器(Manager)的distinct()方法,另一种是在查询函数(QuerySet)调用时使用。

使用模型管理器的方式

MyModel.objects.distinct(*fields)

其中,fields是可选参数,表示需要去重的字段。如果不指定fields,则使用模型的所有字段进行去重。

使用查询函数的方式

MyModel.objects.filter(django_query_filter).distinct(*fields)

其中,django_query_filter是Django查询表达式,fields是可选参数,表示需要去重的字段。同样地,如果不指定fields,则使用模型的所有字段进行去重。

示例

以下是使用distinct()函数的两个实例:

示例一

我们有一个模型Student,它有两个字段:nameage。我们现在要查询Student表中不同年龄的人数。

使用模型管理器的方式:

from django.db.models import Count
result = Student.objects.values('age').annotate(Count('age')).distinct()

解析:我们使用values()方法指定需要查询的字段age,然后使用annotate()方法将这个字段上的计数设置为Count('age')。最后,我们使用distinct()方法去重获取结果。

使用查询函数的方式:

result = Student.objects.values('age').annotate(Count('age')).filter(django_query_filter).distinct()

解析:和上述示例一样,只不过我们加入了filter()函数进行过滤。

示例二

我们有一个模型Order,它有两个字段:order_datecustomer_name。我们现在要查询2021年内不同客户的订单数以及最早订单日期。

使用模型管理器的方式:

from django.db.models.functions import TruncMonth
from django.db.models import Min, Count
result = Order.objects.annotate(month=TruncMonth('order_date')).values('month', 'customer_name').annotate(Count('id'), Min('order_date')).filter(order_date__year=2021).distinct('customer_name')

解析:我们使用annotate()方法将查询结果个数和最早订单日期一起查询出来,然后使用distinct()方法去重客户名称。

使用查询函数的方式:

result = Order.objects.annotate(month=TruncMonth('order_date')).values('month', 'customer_name').annotate(Count('id'), Min('order_date')).filter(django_query_filter, order_date__year=2021).distinct('customer_name')

解析:和上述示例一样,只不过我们加入了filter()函数进行过滤。