Django选择计数

时间:2015-05-21 16:24:03

标签: django django-models django-orm

我对Django很新,我想让用户拥有的客户总数(我的用户将通过我的网站销售一些东西)所以我有一个名为orders的表,我保留user_id购买的用户和正在购买的product_id。每个产品ID都与拥有用户的产品(我正在进行查询的产品)相关:

select COUNT(distinct(o.user_id)) as total_clients from `order` o 
    inner join product p on p.id=o.product_id where p.user_id=32;

用户ID 32已登录,我想向他展示有多少客户购买了他的产品。

我希望在get而不是filter中执行此操作,因为它更有意义。

这是我的逻辑告诉我写的内容:

clients = Order.objects.get(
    status = Order.COMPLETED,
    product__user = self.user
).annotate(
    total_clients = Count( 'user', distinct = True )
)

return clients.total_clients

。以及它返回的内容:

Exception Type: MultipleObjectsReturned
Exception Value:  get() returned more than one Order -- it returned 2!

我可能正在运行查询而不是使用orm,但我不想这样做。这是一个相当简单的查询,我确信Django非常容易处理,我想避免在代码中编写字符串。

这是我的模型设置:

class UserProfile( models.Model ):
    user = models.OneToOneField( User, related_name = 'profile' )
    ....


    def get_total_clients( self ):
        clients = Order.objects.get(
            status = Order.COMPLETED,
            product__user = self.user
        ).annotate(
            total_clients = Count( 'user', distinct = True )
        )

        return clients.total_clients


class Order( models.Model ):
    PENDING = 0
    COMPLETED = 1
    REFUNDED = 2

    STATUS_CHOICES = (
        (PENDING, "Pending"),
        (COMPLETED, "Completed"),
        (REFUNDED, "Refunded"),
    )

    user = models.ForeignKey( User, related_name = "orders" )
    product = models.ForeignKey( Product, related_name = "orders" )
    amount = models.DecimalField( max_digits = 6, decimal_places = 2, default = 0.00 )
    status = models.SmallIntegerField(
        choices = STATUS_CHOICES, default = PENDING, db_index = True
    )


class Product( models.Model ):
    user = models.ForeignKey( User, related_name = "unlocks" )
    name = models.CharField( max_length = 255 )

2 个答案:

答案 0 :(得分:1)

Django queryset有一个count方法:

clients = Order.objects.filter(
                            status = Order.COMPLETED,
                            product__user = self.user
             )
return clients.count()

答案 1 :(得分:0)

如果我说得对,那么您对从用户订购产品的消费者数量感兴趣。一些docs,可能会有所帮助。

我的建议是:

result = Product.objects.distinct().filter(
    # or any query:
    orders__status=Order.COMPLETED,
    user=default_user

).aggregate( # see the difference between aggregate() and annotate()
    total_users=Count('orders__user', distinct=True)
)

我希望结果为:{'total_users': NUM_OF_USERS}

在原始SQL中,它将类似于:

SELECT DISTINCT COUNT(DISTINCT "main_order"."user_id") AS 
"total_users" FROM "main_product" INNER JOIN "main_order" ON (     
"main_product"."id" = "main_order"."product_id" ) WHERE 
("main_order"."status" = STATUS AND "main_product"."user_id" = USER_ID)

这就是你想要的吗?