Django:注释后合并查询集的问题

发布于 2024-08-24 11:56:13 字数 761 浏览 8 评论 0 原文

我有一个“对话”管理器,如下所示:

class AnnotationManager(models.Manager):
def get_query_set(self):
    return super(AnnotationManager, self).get_query_set().annotate(
        num_votes=Count('vote', distinct=True),
        num_comments=Count('comment', distinct=True),
        num_commentators = Count('comment__user', distinct=True),
    )

投票和评论有一个对话的外键。评论有一个用户的外键。当我这样做时:

dialogs_queryset = Dialog.public.filter(organization=organization)
dialogs_popularity = dialogs_queryset.exclude(num_comments=0) | dialogs_queryset.exclude(num_votes=0)

...dialogs_popularity 永远不会返回组合,而只会返回评论数超过 0 的对话框,或者如果我更改 OR 的顺序,则返回投票数超过 0 的对话框!

对我来说,预期的行为是获得超过 0 票的对话框和超过 0 条评论的对话框。

我缺少什么?或者这里的注释行为是否存在错误?

I have a manager for "Dialog" looking like this:

class AnnotationManager(models.Manager):
def get_query_set(self):
    return super(AnnotationManager, self).get_query_set().annotate(
        num_votes=Count('vote', distinct=True),
        num_comments=Count('comment', distinct=True),
        num_commentators = Count('comment__user', distinct=True),
    )

Votes and Comments has a ForeignKey to Dialog. Comments has a ForeignKey to User. When I do this:

dialogs_queryset = Dialog.public.filter(organization=organization)
dialogs_popularity = dialogs_queryset.exclude(num_comments=0) | dialogs_queryset.exclude(num_votes=0)

...dialogs_popularity will never returned the combination, but only the dialogs with more than 0 comments, or if I change the order of the OR, the dialogs with more than 0 votes!

To me, the expected behavior would be to get the dialogs with more than 0 votes AND the dialogs with more than 0 comments.

What am I missing? Or is there a bug in the annotation behavior here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

用心笑 2024-08-31 11:56:13

想要进行投票和评论的对话吗?

# must have both a vote and a comment
# aka.  has_comments_and_votes = has_comments AND has_votes
#                              = !(has_no_comments OR has_no_votes)
has_comments = ~Q(num_comments=0)
has_votes = ~Q(num_votes=0)

dialogs_queryset.filter(num_comments__ne=0, num_votes__ne=0)
# or with Q objects
dialogs_queryset.filter(has_comments & has_votes)
dialogs_queryset.exclude(~has_comments | ~has_votes)

或者有投票、评论或两者兼而有之的对话。 (你想要什么基于评论。)

# must have at least 1 vote or 1 comment
# aka. has_comments_or_votes = has_comments OR has_votes
#                            = !(has_no_comments AND has_no_votes)
dialogs_queryset.exclude(num_comments=0, num_votes=0)
# again with Q objects
dialogs_queryset.filter(has_comments | has_votes)  # easiest to read!
dialogs_queryset.exclude(~has_comments & ~has_votes)

我添加了 Q 对象 示例,因为“|”在您的代码示例中似乎暗示了它们,它们使创建 ORed 查询变得更容易。

编辑:
我添加了 has_commentshas_votes 以使内容更容易阅读。

Did want dialogs with both votes and comments?

# must have both a vote and a comment
# aka.  has_comments_and_votes = has_comments AND has_votes
#                              = !(has_no_comments OR has_no_votes)
has_comments = ~Q(num_comments=0)
has_votes = ~Q(num_votes=0)

dialogs_queryset.filter(num_comments__ne=0, num_votes__ne=0)
# or with Q objects
dialogs_queryset.filter(has_comments & has_votes)
dialogs_queryset.exclude(~has_comments | ~has_votes)

Or dialogs having either votes, comments or both. (What you want based on comment.)

# must have at least 1 vote or 1 comment
# aka. has_comments_or_votes = has_comments OR has_votes
#                            = !(has_no_comments AND has_no_votes)
dialogs_queryset.exclude(num_comments=0, num_votes=0)
# again with Q objects
dialogs_queryset.filter(has_comments | has_votes)  # easiest to read!
dialogs_queryset.exclude(~has_comments & ~has_votes)

I added the Q objects examples because the "|" in your code sample seemed to be hinting at them and they make it easier to create ORed queries.

EDIT:
I added has_comments and has_votes to make things a little easier to read.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文