2016-08-05 40 views
0

假设我在我的模型(模型客户端)中有客户端,并且假设每个客户端都有一个购物车(模型Cart)。每个购物车都有很多物品(型号CartItems),然后结束,每个物品与一个产品(型号产品)有关系。Django,Select related,Average,ManyToMany field

现在,这里是我的问题。我希望每个客户都拥有所有购物车的平均值,该购物车以每个购物车的所有项目总和为基础。所以我会尽量在下面给你更详细的介绍。

试着想象的关系是这样的方向:我已经找到

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: 客户端 - > Cart-> CartItems < - 产品

简化每个模型的描述解决方案,并会是这样的查询:

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'模型的模式?

+0

答案是不要打扰。只需使用原始查询。没有理由不这样做(除了事实上,如果您多次遍历查询集,每次都会执行查询) – e4c5

+0

但是,这样做可以正常使用Paginator,就好像它是查询集一样吗? – user3707567

+0

你是对的,默认的paginators不能用于rawqueryset – e4c5

回答

0

你做前人的精力类似:

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

注意,注释不返回的查询集,你应该返回的值。

延伸阅读:Aggregations in Django

+0

Client.objects.select_related()。order_by(order_by).annotate(total = Sum(F('cadcp__cpi__product__value')* F('cadcp__cpi__quantity'),output_field = models .DecimalField()))。extra(select = {'n_cart':'COUNT(DISTINCT'cart'.'id')'})。有了这个代码,我可以检索每个购物车的价格总额和客户购物车的数量,所以我可以做total/n_cart并获得平均值,但这种方式我不能按平均值排序。任何想法如何解决这个问题? 感谢您的回答,它帮助了很多。 – user3707567