【问题标题】:Django: Annotate the count of the number of duplicate values for each objectDjango:注释每个对象的重复值数量的计数
【发布时间】:2019-01-01 14:52:11
【问题描述】:

我有一个名为 Product 的模型,如下所示。产品可以具有相同的字段“bc_sku”。

class Product(models.Model)

    bc_sku                          = models.IntegerField(null=True, blank=True)
    product_type                    = models.CharField(null=True, blank=True, max_length=50)
    merchant                        = models.CharField(null=True, blank=True, max_length=50)
    product_price                   = models.DecimalField(null=True, blank=True, max_digits=10, decimal_places=2)

例如,假设我有这个对象列表

    bc_sku | product_type | merchant | product_price
    100    | good         | A        | 1.00
    100    | bad          | B        | 2.00
    100    | bad          | C        | 3.00
    101    | good         | A        | 7.00
    101    | bad          | B        | 5.00

我想做的是创建一个查询,用重复的数量以及每个“bc_sku”的最低价格来注释每个“好”产品。然后我希望能够在模板中使用这些对象和值。

    bc_sku | product_type | merchant | dup_count | min_price
    100    | good         | A        | 3         | 1.00
    101    | good         | A        | 2         | 5.00

任何帮助都将不胜感激,因为我正在努力获取注释和过滤器以使其当前正常工作。

【问题讨论】:

    标签: python django annotations


    【解决方案1】:

    最初的愿望是用window function,可惜是not allowed 结合annotate(Window(...))和filter(...)

    答案是:

    from django.db.models import OuterRef, Subquery, Count, Min
    
    subquery = Product.objects.filter(bc_sku=OuterRef('bc_sku')).values('bc_sku')
                              .annotate(dup_count=Count('*'), min_price=Min('product_price'))
    Product.objects.filter(product_type='good')
                   .annotate(dup_count=Subquery(subquery.values('dup_count')), 
                             min_price=Subquery(subquery.values('min_price')))
    

    您可以在docs中找到有关此查询如何工作的详细信息

    【讨论】:

    • 感谢您的回复。这看起来好像会起作用,但是我收到以下错误:表达式包含混合类型。您必须设置 output_field。
    • 别担心,我解决了!我将我的子查询包装在 ExpressionWrapper 中,然后使用 output_field=DecimalField() 进行排序。非常感谢您的帮助。
    • 很高兴听到! :) 你使用什么 Django 版本?我使用的是 2.0,当我使用您在问题中提到的定义和数据进行尝试时,它按预期工作
    • 我使用的是 2.0.7。
    猜你喜欢
    • 2020-03-10
    • 2018-07-21
    • 2023-02-14
    • 2019-01-13
    • 1970-01-01
    • 2017-04-14
    • 2021-07-12
    • 2012-04-19
    • 1970-01-01
    相关资源
    最近更新 更多