【问题标题】:django - how to separate a queryset?django - 如何分离查询集?
【发布时间】:2013-11-29 22:44:04
【问题描述】:

我正在用户之间创建一个消息传递应用程序。希望完全有帮助,我想出了业务逻辑,我认为会起作用。所以现在,我可以发送消息并获取特定用户(例如 A)的所有消息(发送和接收)。但是我被困在查询或分离每个用户的消息(A的所有发送/接收的消息)(例如,A和B发送/接收的消息,A和C发送/接收的消息)。下面是我的models.py。请看一看,请帮助我。或者如果有更好的出路,请告诉我。将不胜感激。谢谢。

models.py

class Thread(models.Model):
    sender = models.ForeignKey(User, related_name="sender_set")
    recipient = models.ForeignKey(User, related_name="recipient")
    message = models.TextField()
    date = models.DateTimeField(default=datetime.now)

# To get all the messages of A
>>> conversation = Thread.objects.filter(Q(sender=A) | Q(recipient=A))
[<Thread: A to B><Thread: C to A><Thread: B to A><Thread: A to C><Thread: A to B>]

如何为每个用户获取单独的conversation?希望我已经澄清了我的观点。谢谢。

【问题讨论】:

  • 您想要的是获取 2 个特定用户之间的所有消息还是来自 1 个特定用户的所有消息(发送和接收)?
  • 我想获得 A 和 B 以及 A 和 C 的单独消息集。
  • 您是否尝试使用 2 个查询来处理此问题?
  • 对不起,我不关注。你能详细说明一下吗?

标签: django django-models django-orm


【解决方案1】:

我鼓励您不要重新发明轮子。我最近有一个类似的任务,我发现简单地采用优秀的user_messages 项目中的代码非常容易。为了采用和理解我在做什么,我需要了解所使用的 DB 模型,如下所示:

基本上您的User 模型(无论是标准模型还是您覆盖标准模型的模型)具有:

  • 1:N(一对多)Message
  • 1:N(一对多)UserThread

Thread 具有 1:N UserThread,这使得将消息分组到线程下很容易,具体取决于您向哪个用户显示线程。

以这种方式对数据进行建模使得为每个用户(您所问的)检索单独的对话变得轻而易举。

请查看他们的models.py 和相关的managers.py。您将意识到他们做出并放入代码中的良好设计决策。我不得不自己扩展它,因为它不能满足我所有的用例。但我确实发现它很容易扩展。

顺便说一句:我是通过查看django packages already available for messages 找到的user_messages 使用非常有用的djangopackages.com 网站。

【讨论】:

  • 嗨!非常感谢你的建议。我看到了models.py,但我仍在努力掌握这一点。你能解释一下吗...
  • 嗨@Aamu,你能具体说明你需要解释什么吗?如果您发现难以理解 db 模型,请在一张纸上绘制 DB 图,并理解它。它不会在几秒钟内发生。此外,运行并了解模型和管理器的单元测试。
  • 据我了解:1)一个Thread有一个主题,可以有很多用户。 2)User 可以有多个线程,具有未读和删除属性。就这样。我无法理解Message 类,以及为什么SubjectContent 分开保存?请您向我解释一下,如果我的理解有误,请纠正我。
  • 每个Thread 保留一个subjectcontent 是实际消息的文本,按Message 保留。想想 FB 对话是如何运作的,这非常相似。
【解决方案2】:
(eg. messages sent/received by A and B, messages sent/received by A and C)

如果我理解正确你的问题;您想要的是获取 2 个用户之间的所有消息(发送或接收)。因此,根据您的模型设计,这 2 个查询可以满足您的需求:

c1 = Thread.objects.filter(sender=A, recipient=B)
c2 = Thread.objects.filter(sender=B, recipient=A)

total = list(c1) + list(c2) # this will give you all messages between A and B

您可以创建一个函数来为多个特定用户处理此问题:

def separate_messages(user1, user2):
    c1 = Thread.objects.filter(sender=user1, recipient=user2)
    c2 = Thread.objects.filter(sender=user2, recipient=user1)

    total = list(c1) + list(c2)
    return total

users = [B, C, D, E]
const_user = A

for user in users:
    print separate_messages(const_user, user)

【讨论】:

  • 是的,这就是我想要的。但是假设有很多 A 和不同用户的消息,我该如何分离它们呢?
  • 我不明白。上面,c1 为您提供 A 和 B 之间的消息。没有其他用户。
  • 是的。对不起。请让我再详细说明一下。现在我们知道 B 存在,所以上面的代码可以正常工作。但是在 A 和 C、A 和 D、A 和 E、.. 或 A 和 n 之间可以有许多其他消息。不仅仅是 B。那么我该如何将所有这些消息从不同的用户中分离出来呢?我是否必须在每个用户之间进行循环,例如:sender != Arecipient != A
  • 如果以上结果正常;您可以创建一个带有 2 个参数的函数:一个是发件人,一个是收件人。然后,您可以将该函数与 for 循环一起使用。
  • 添加了该功能。请看答案。 @Aamu
猜你喜欢
  • 2019-07-01
  • 2014-01-31
  • 2021-05-02
  • 2016-12-28
  • 2019-06-04
  • 2014-08-28
  • 2016-02-01
  • 1970-01-01
  • 2020-06-20
相关资源
最近更新 更多