【问题标题】:Annotating in Django query based on a many to many relationship基于多对多关系在 Django 查询中进行注释
【发布时间】:2020-12-09 21:22:04
【问题描述】:

我正在使用带有 Postgres 的 Django。

我有一个名为 Product 的对象和另一个名为 UserProfile 的对象。当用户喜欢某个产品时,该产品会记录在 UserProfile 的字段中,如下所示:

watchedProducts = models.ManyToManyField('Product', related_name='user_where_watched', blank=True)

现在我要做的是查询产品表并按喜欢的数量订购产品。

我所拥有的(它不起作用)是:

products = Product.objects.filter(fullSearchCondition).distinct().annotate(numOfLikes=RawSQL('SELECT COUNT(id) FROM "myapp_userprofile_watchedProducts" WHERE "product_id"=%s',(F('id'),))).order_by("numOfLikes")

我没有得到的是如何将产品 ID 注入到查询中。

我还研究了 Django 的自定义表达式函数,但对我来说它看起来更复杂。

有人可以告诉我这样做的好方法吗?

【问题讨论】:

    标签: python sql django postgresql


    【解决方案1】:

    您可以使用以下方式注释查询集:

    from django.db.models import Count
    
    products = Product.objects.filter(fullSearchCondition).annotate(
        numOfLikes=Count('user_where_watched')
    ).order_by('numOfLikes')

    可能出现的唯一问题是fullSearchCondition 遵循一对多或多对关系(除'user_where_watched' 之外),然后多次检索Product,但这会发生都带有原始查询和注释,因为 .distinct() 要求 all 字段是不同的,包括喜欢的数量。

    【讨论】:

    • 嗯,我明白了,所以你会说我应该在查询之后以某种方式应用 distinct() 吗?我试图用 distinct() 实现的只是具有不同的 id,因此查询不会返回相同的 Product 两次。这是因为 fullSearchCondition 包括按名称、产品所有者等进行搜索。
    • @Elendurwen:只要你只过滤Product的直接字段,或者你关注ForeignKeys(单向)或OneToOneFields(双向),相同的Product 不能返回两次。只有当您反向过滤ForeignKeys 或ManyToManyFields 时,才能多次检索相同的记录。
    猜你喜欢
    • 2021-06-24
    • 1970-01-01
    • 1970-01-01
    • 2021-03-07
    • 2023-03-08
    • 2013-11-05
    • 2015-10-26
    • 1970-01-01
    相关资源
    最近更新 更多