【问题标题】:Django selecting a countDjango 选择计数
【发布时间】:2015-05-21 16:24:02
【问题描述】:

我对 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 )

【问题讨论】:

  • >> “我想在 get 而不是 filter 中执行此操作,因为它更有意义。”但为什么呢?
  • 因为 get 应该返回一个结果,因为这是我要挑选的计数。
  • 你能发一下你的models.py吗?
  • @sobolevn 我更新了我的问题。

标签: django django-models django-orm


【解决方案1】:

Django 查询集有一个count 方法:

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

【讨论】:

  • 是的,我知道,但我有多个查询,其中一些使用 SUM,我遇到了同样的问题,所以最后不涉及 .count() 的另一种解决方案将教我如何做到这两点。 +1 可能的解决方案。
  • 是的,抱歉,忘记将 get 更改为 filter。即使没有完全回答您的请求,也已编辑答案。
【解决方案2】:

如果我没猜错,您就会对从用户那里订购产品的消费者数量感兴趣。一些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)

这是你想要的吗?

【讨论】:

  • 还有一个一般建议,如果您是 Django 新手,请使用 django-debug-toolbar 监控您的数据库调用。
  • 我正在使用它,这就是我看到查询错误的方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-13
  • 1970-01-01
  • 2012-03-05
  • 2012-07-05
  • 2012-06-07
  • 2015-08-27
  • 1970-01-01
相关资源
最近更新 更多