【问题标题】:How can I filter django queryset again to get unique parameters?如何再次过滤 django 查询集以获取唯一参数?
【发布时间】:2020-01-10 19:47:48
【问题描述】:

您好,我正在尝试为每个用户接收最后一条消息。我已经过滤掉了消息,但我收到了一个用户的许多消息。如何获取用户的最后一条消息。

   queryset=MessageModel.objects.filter(
          Q(sUser=self.request.user) | Q(rUser=self.request.user)
          ).order_by('-id')

  return queryset

我从过滤中得到这个列表。

[
       {
                "message": "Hi b do you want to buy? 2",
                "sUser": 1,
                "rUser": 15,
                "sent": true,
                "pk": 8,
                "user": {
                    "pk": 15
                }
            },
            {
                "message": "a to c",
                "sUser": 1,
                "rUser": 16,
                "sent": true,
                "pk": 7,
                "user": {
                    "pk": 16
                }
            },
            {
                "message": "No thanks not buying this time",
                "sUser": 15,
                "rUser": 1,
                "sent": false,
                "pk": 6,
                "user": {
                    "pk": 15
                }
            },
            {
                "message": "c to a",
                "sUser": 16,
                "rUser": 1,
                "sent": false,
                "pk": 4,
                "user": {
                    "pk": 16
                }
            },
            {
                "message": "Hi b do you want to buy?",
                "sUser": 1,
                "rUser": 15,
                "sent": true,
                "pk": 1,
                "user": {
                    "pk": 15
                }
            }

        ]

我只想收到带有 pk 8 和 7 的消息,因为它是给用户 15 和 16 的最后一条消息,但我收到了 15 和 16 的所有消息。

【问题讨论】:

    标签: django sqlite django-models filter django-filter


    【解决方案1】:

    好吧,我猜你会选择像 facebook messenger 的仪表板这样的类型。先获取用户的相关消息

     relatedMessage=MessageModel.objects.filter(
              Q(sUser=self.request.user) | Q(rUser=self.request.user)
              ).order_by('-id')
    

    将第一条消息添加到列表中

     convoList.append(relatedMessage.latest('id')) #since first message is unique
    

    然后从每个人中找出朋友,以便您可以区分朋友的确切身份(发送者或接收者可能是您或朋友,因为我们正在过滤消息发送者或接收者是您或您的朋友)。

      friend = message.sUser
        if message.sUser==self.request.user:
            friend=message.rUser
    

    太棒了!你找到了你的朋友是谁。 现在,对于relatedMessage 中的每条消息,检查您朋友的消息是否存在于您的 convoList 中。如果它不存在,则将其添加到 convolist。最后创建序列化程序并返回其数据或查询集,无论您喜欢什么。

    这是首选,因为它只对数据库进行一次查询,因此在服务器中创建了计算部分。如果您先从数据库中获取相关用户,然后再次过滤消息,由于数据库中的两次巨大查询,这将非常昂贵。

    【讨论】:

      【解决方案2】:

      你必须

        queryset=MessageModel.objects.filter(
                Q(sUser=self.request.user) | Q(rUser=self.request.user)
                ).order_by('-id')
        if queryset.exists():
      
            return queryset[0]
        else:
            return None
      

      希望这对你有用

      【讨论】:

        【解决方案3】:

        我不确定您原始查询中的 Q 表达式是否与您要求的匹配,但我们假设您想要每个用户最近收到的消息,并且您可以依赖于 id 的排序,这样id 越高,越近。

        如果您使用支持DISTINCT ON 的数据库后端,您可以执行以下操作:

        most_recent_messages = MessageModel.objects.all().order_by('rUser', '-id').distinct('rUser')
        

        例如,如果您想将查询集进一步过滤到特定用户,您可以添加filter 而不是all

        【讨论】:

          猜你喜欢
          • 2018-05-12
          • 1970-01-01
          • 2016-07-28
          • 1970-01-01
          • 2016-02-01
          • 1970-01-01
          • 1970-01-01
          • 2020-03-08
          • 2021-09-16
          相关资源
          最近更新 更多