Django, Select related, Average, ManyToMany field



假设我的模型中有客户端(model Client),并且假设每个客户端都有一个购物车(model cart)。每个购物车都有许多商品(型号CartItems),最后,每个商品都与一个产品(型号product)有关系。

现在,我的问题来了。我想要每个客户的所有购物车的平均值,它基于每个购物车的所有项目的总和。因此,我将尝试在下面向您展示更多细节。

试着想象一下这种关系的方向:客户端->购物车->购物车项目&lt-产品

每个型号的简化描述:

Client (
  id #pk
)
Cart (
  id #pk
  client_id #fk that references to Client.id
)
CartItems (
  id #pk
  cart_id #fk that references to Cart.id
  product #fk that references to Product.id
)
ProductId (
  id #pk
  value # The price of the product
)

在纯SQL中,我找到了解决方案,类似于以下查询:

SELECT * FROM Client
INNER JOIN Cart ON Client.id = Cart.client_id
INNER JOIN 
(SELECT AVG(c.total) AS average, cart_id FROM
    (SELECT SUM(Product.price) AS total, CartItems.cart_id AS cart_id
    FROM CartItems
    INNER JOIN Product ON CartItems.product = Product.id
    GROUP BY CartItems.cart_id) AS c GROUP BY c.cart_id) AS d
ON d.cart_id = Cart.id;

有人知道如何将这个查询转换为Django模型的模式吗?

你可以做一些类似的事情:

Cart.objects.values('client_id').annotate(cant=Sum('cart_id__product__value')).aggregate(Avg('cant'))

请注意,注释不返回查询集,您应该返回值。

进一步阅读:Django 中的聚合

我的答案来得很晚,但我在寻找类似问题的解决方案时遇到了这个问题。

在我的例子中,Cart和CartItems之间有一个ManyToManyField关系,这使得它相当简单。

模型现在看起来像这个

Cart (
  id #pk
  client_id #fk that references to Client.id
  items #manytomany relationship to CartItems
)
CartItems (
  id #pk
  product #fk that references to Product.id
)

为了获得每个购物车的平均值,查询看起来就像这个

Cart.objects.annotate(carts_avg=Avg('items__product__value'))

最新更新