【问题标题】:Django annotate : count of ModelB entries not in manytomany relationship with ModelADjango注释:与ModelA不存在多对多关系的ModelB条目计数
【发布时间】:2017-03-05 08:39:26
【问题描述】:

在这种特殊情况下,ModelA 是默认的 Django 模型。用户

ModelB 实现为:

class ModelB(models.Model):
    user = models.ManyToManyField(User)
    #some other stuff

1.对于每个 ModelB 记录,统计与其没有关系的 User 记录

我设法做到了:

ModelB.objects.all().annotate(user_count=User.objects.count()-Count('user'))

它有效,但感觉就像一个黑客。有没有更好的方法来做到这一点(同时仍然使用annotate())?

2。带过滤

我将之前的查询修改为使用当前登录的用户进行过滤,这样我就可以为每个用户显示自定义内容。无论登录用户如何,我都打算保持与查询 #1 中相同的 user_count 值:

ModelB.objects.filter(
    user=request.user
).annotate(
    user_count=User.objects.count()-Count('user')
)

编辑:过滤在annotate 之后按预期工作:

ModelB.objects.annotate(
    user_count=User.objects.count()-Count('user')
).filter(
    user=request.user
)

仍在寻找比 User.objects.count()-Count('user') 更好的方法来计算每个 ModelB 记录的非相关用户记录。

感谢您的帮助!

【问题讨论】:

    标签: django django-models django-queryset django-orm django-aggregation


    【解决方案1】:

    我不认为您的代码正在做您认为它正在做的事情。 Count('user') 不返回数据库中的用户总数,而只返回与该 ModelB 对象相关的用户数。要使用这个解决方案(你自己说 - 是一种非常糟糕的方式来做 IMO),你可能应该使用User.objects.count()

    如果我正确理解你的意愿,那么这种方法应该会给你你想要的数字:

    User.objects.filter(modelb_set__isnull=True).count() # "modelb_set" is the default Django related name, if you've set another one, use that.
    # or (depending on which you want)
    ModelB.objects.filter(user__isnull=True).count()
    

    【讨论】:

    • @nonesk 是你想要的还是我误解了什么?
    • 对不起,我之前的评论是一个错误。我知道Count('user') 是关于ModelB 的相关用户数量。我想要做的是将 non-related 用户的数量提供给 ModelB,并将 annotate() 提供给我的 ModelB 查询集。我确实尝试了您建议的解决方案,但无法使其与 annotate 一起使用。
    • @nonesk 在我看来,您的方法是扭曲的,因为根据定义,注释是指与您注释它们的对象相关的度量。为每个模型实例注释一个随机整数(此时为不相关用户的数字)是没有意义的,因为该数字始终相同,是一个常数。您能解释一下最终目标是什么,然后我或许可以进一步帮助您?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-06
    • 2017-07-03
    • 2013-08-29
    • 1970-01-01
    • 2011-06-02
    • 2017-12-16
    • 2018-07-05
    相关资源
    最近更新 更多