如何获取annotate Count的主键

How to get the Primary key of annotate Count

嗨,Whosebug 社区,我的问题是关于 django annotate。

基本上我要做的是从两个不同表中的两个不同字段中找到具有相同值的重复值。

这是我的models.py

class Order(models.Model):
    id_order = models.AutoField(primary_key=True)
class OrderDelivery(models.Model):
    order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True, blank=True)
    delivery_address = models.TextField()
class OrderPickup(models.Model):
    order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True, blank=True)
    pickup_date = models.DateField(blank=True, null=True)

这是我当前的代码:

dup_job = Order.objects.filter(
        orderpickup__pickup_date__range=(start_date, end_date)
    ).values(
        'orderdelivery__delivery_address',
        'orderpickup__pickup_date',
    ).annotate(
        duplicated=Count('orderdelivery__delivery_address')
    ).filter(
        duplicated__gt=1
    )

根据我所拥有的,我得到这样的结果(delivery_address 出于隐私目的被省略):

{'orderdelivery__delivery_address': '118A', 'orderpickup__pickup_date': datetime.date(2022, 3, 9), 'duplicated': 2}
{'orderdelivery__delivery_address': '11', 'orderpickup__pickup_date': datetime.date(2022, 3, 2), 'duplicated': 6}
{'orderdelivery__delivery_address': '11 A ', 'orderpickup__pickup_date': datetime.date(2022, 3, 3), 'duplicated': 5}
{'orderdelivery__delivery_address': '21', 'orderpickup__pickup_date': datetime.date(2022, 3, 10), 'duplicated': 3}
{'orderdelivery__delivery_address': '642', 'orderpickup__pickup_date': datetime.date(2022, 3, 7), 'duplicated': 2}
{'orderdelivery__delivery_address': '642', 'orderpickup__pickup_date': datetime.date(2022, 3, 8), 'duplicated': 2}
{'orderdelivery__delivery_address': 'N/A,5', 'orderpickup__pickup_date': datetime.date(2022, 3, 8), 'duplicated': 19}

有没有办法得到 'duplicated' 中的 id_order? 我试过在 .values() 中包含 id_order 但输出将不准确,因为注释按 id_order 而不是 delivery_address 分组。

提前致谢

您可以获得具有 Min [Django-doc](或 Max)聚合的最小(或最大)项目:

from django.db.models import Min

dup_job = Order.objects.filter(
    orderpickup__pickup_date__range=(start_date, end_date)
).values(
    'orderdelivery__delivery_address',
    'orderpickup__pickup_date',
).annotate(
    <strong>min_id_order=Min('id_order')</strong>
    duplicated=Count('orderdelivery__delivery_address')
).filter(
    duplicated__gt=1
)

, you can make use of the ArrayAgg [Django-doc] 生成列表:

# PostgreSQL only

from django.contrib.postgres.aggregates import ArrayAgg

dup_job = Order.objects.filter(
    orderpickup__pickup_date__range=(start_date, end_date)
).values(
    'orderdelivery__delivery_address',
    'orderpickup__pickup_date',
).annotate(
    <strong>min_id_order=ArrayAgg('id_order')</strong>
    duplicated=Count('orderdelivery__delivery_address')
).filter(
    duplicated__gt=1
)