Django的注释计数错误(可能重复?)

发布于 2025-02-03 02:23:42 字数 2939 浏览 2 评论 0原文

我有一个模型chatmessage具有字段发件人,它是foreferkey to user模型。

我正在尝试注释所有尚未读取的所有chatmessage对象(例如,seaw_at__isnull = true)。

对于给定的用户,只有一条发送的消息,sead_at__isnull = true,但django返回11。

User.objects.select_related(...).annotate(
            sent_unread_messages=Count('sent_chat_messages',
                                       filter=Q(sent_chat_messages__seen_at__isnull=True))).get(pk=1234).sent_unread_messages

您知道问题在哪里吗?

编辑:

class ChatMessageManager(models.Manager):
    def get_queryset(self) -> models.QuerySet:
        return super().get_queryset().select_related('sender', 'recipient')

    def as_sender_or_recipient(self, user) -> models.QuerySet:
        return self.get_queryset().filter(Q(sender=user) | Q(recipient=user))

class ChatMessage(BaseModel):
    objects = ChatMessageManager()
    sender = models.ForeignKey('users.User', verbose_name='Odosielateľ', null=True, blank=True,
                               on_delete=models.SET_NULL, related_name='sent_chat_messages')

    recipient = models.ForeignKey('users.User', verbose_name='Adresát', null=True, blank=True,
                                  on_delete=models.SET_NULL, related_name='received_chat_messages')

    content = models.TextField('Obsah')
    attachment = models.FileField('Príloha', null=True, blank=True)
    attachment_filename = models.CharField('Názov prílohy', null=True, blank=True, max_length=128)
    meta = models.JSONField(verbose_name='Meta', null=True, blank=True, help_text='must be JSON')
    seen_at = models.DateTimeField('Prečítané o', null=True, blank=True)



class CustomUserManager(UserManager):
    def get_queryset(self):
        return super().get_queryset().select_related('staff_profile', 'client_profile').annotate(
            sent_unread_messages=Count('sent_chat_messages',
                                       filter=Q(sent_chat_messages__seen_at__isnull=True))).annotate(
            received_unread_messages=Count('received_chat_messages',
                                           filter=Q(received_chat_messages__seen_at__isnull=True))).annotate(
            sent_latest_message=Subquery(
                ChatMessage.objects.filter(sender=OuterRef('pk')).order_by('-created').values('content')[:1])).annotate(
            sent_latest_message_dt=Subquery(
                ChatMessage.objects.filter(sender=OuterRef('pk')).order_by('-created').values('created')[:1])).annotate(
            received_latest_message=Subquery(
                ChatMessage.objects.filter(recipient=OuterRef('pk')).order_by('-created').values('content')[
                :1])).annotate(
            received_latest_message_dt=Subquery(
                ChatMessage.objects.filter(recipient=OuterRef('pk')).order_by('-created').values('created')[:1]))

I have a model ChatMessage that has a field sender which is a ForeignKey to User model.

I'm trying to annotate a number of all the ChatMessage objects that haven't been read (eg. have seen_at__isnull=True).

For a given user, there is only one sent message with seen_at__isnull=True but Django returns 11.

User.objects.select_related(...).annotate(
            sent_unread_messages=Count('sent_chat_messages',
                                       filter=Q(sent_chat_messages__seen_at__isnull=True))).get(pk=1234).sent_unread_messages

do you know where is the problem?

EDIT:

class ChatMessageManager(models.Manager):
    def get_queryset(self) -> models.QuerySet:
        return super().get_queryset().select_related('sender', 'recipient')

    def as_sender_or_recipient(self, user) -> models.QuerySet:
        return self.get_queryset().filter(Q(sender=user) | Q(recipient=user))

class ChatMessage(BaseModel):
    objects = ChatMessageManager()
    sender = models.ForeignKey('users.User', verbose_name='Odosielateľ', null=True, blank=True,
                               on_delete=models.SET_NULL, related_name='sent_chat_messages')

    recipient = models.ForeignKey('users.User', verbose_name='Adresát', null=True, blank=True,
                                  on_delete=models.SET_NULL, related_name='received_chat_messages')

    content = models.TextField('Obsah')
    attachment = models.FileField('Príloha', null=True, blank=True)
    attachment_filename = models.CharField('Názov prílohy', null=True, blank=True, max_length=128)
    meta = models.JSONField(verbose_name='Meta', null=True, blank=True, help_text='must be JSON')
    seen_at = models.DateTimeField('Prečítané o', null=True, blank=True)



class CustomUserManager(UserManager):
    def get_queryset(self):
        return super().get_queryset().select_related('staff_profile', 'client_profile').annotate(
            sent_unread_messages=Count('sent_chat_messages',
                                       filter=Q(sent_chat_messages__seen_at__isnull=True))).annotate(
            received_unread_messages=Count('received_chat_messages',
                                           filter=Q(received_chat_messages__seen_at__isnull=True))).annotate(
            sent_latest_message=Subquery(
                ChatMessage.objects.filter(sender=OuterRef('pk')).order_by('-created').values('content')[:1])).annotate(
            sent_latest_message_dt=Subquery(
                ChatMessage.objects.filter(sender=OuterRef('pk')).order_by('-created').values('created')[:1])).annotate(
            received_latest_message=Subquery(
                ChatMessage.objects.filter(recipient=OuterRef('pk')).order_by('-created').values('content')[
                :1])).annotate(
            received_latest_message_dt=Subquery(
                ChatMessage.objects.filter(recipient=OuterRef('pk')).order_by('-created').values('created')[:1]))

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

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

发布评论

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

评论(1

国粹 2025-02-10 02:23:42

您可以尝试使用.distinct()方法(在获取消息时从QuerySet中删除重复元素)吗?

can you try using .distinct() method (which removes the duplicate elements from a queryset) when getting the messages ?

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