代码之家  ›  专栏  ›  技术社区  ›  Bite code

如何使用django orm获取按属性分组的最新条目的值?

  •  0
  • Bite code  · 技术社区  · 14 年前

    我有一个报告模型看起来有点像这样:

    class Report(models.Model):
        date = models.DateField()
        quantity = models.IntegerField()
        product_name = models.TextField()
    

    我知道我可以通过以下方式获得去年某个产品的最后一个条目:

    Report.objects.filter(date__year=2009, product_name="corn").order_by("-date")[0]
    

    我知道我可以按名称对条目进行分组:

    Report.objects.values("product_name")
    

    但是我如何才能得到每种产品的最后一个条目的数量呢?我觉得我会在SQL中这样做(不确定,我的SQL已经生锈了):

    SELECT product_name, quantity FROM report WHERE YEAR(date) == 2009 GROUP_BY product_name HAVING date == Max(date)
    

    我想将max()对象与annotate一起使用,但我不知道如何使用。

    现在,我通过手动添加每个查询的最后一项来为我不能列出的每个产品名称添加一个不同的名称。

    1 回复  |  直到 14 年前
        1
  •  2
  •   istruble kalyan    14 年前

    不完全是使用django orm或SQL的简单查询。我对它的第一个理解是,您可能已经做了很多事情;获取不同的产品和日期对,然后为每个产品和日期对执行单独的查询。

    year_products = Product.objects.filter(year=2009)
    product_date_pairs = year_products.values('product').distinct('product'
            ).annotate(Max('date'))
    [Report.objects.get(product=p['product'], date=p['date__max']) 
            for p in product_date_pairs]
    

    但是,您可以使用q操作符进一步,或者使用一些花哨的方法,将查询计数减少到2而不是n+1。

    import operator
    qs = [Q(product=p['product'], date=p['date__max']) for p in product_date_pairs]
    ored_qs = reduce(operator.or_, qs)
    Report.objects.filter(ored_qs)