考虑以下模型:
class Message(models.Model):
other_model = models.ForeignKey(OtherModel) # OtherModel has owner field
thread_user = models.ForeignKey(User)
posting_user = models.ForeignKey(User)
message = models.TextField()
我要做的是在第三个对象上的两个用户之间进行私人消息传递,在这种情况下,是用户的个人资料。即User A
可以转到User B
的个人资料并发布消息。在上面的模型中:
other_model = OtherModel instance belonging to User A
thread_user = User B
posting_user = User B
如果User A
想要回复,则只有posting_user
更改。这允许用户A和其他用户之间的多个私人对话线程。
但我遇到显示逻辑问题。目前,我只是按照pk排序评论我得到这样的结果:
Message.objects.all():
[
Message<other_model=a, thread_user=b, posting_user=b>, # B to A
Message<other_model=a, thread_user=b, posting_user=a>, # A to B
Message<other_model=a, thread_user=c, posting_user=c>, # C to A
Message<other_model=a, thread_user=b, posting_user=b>, # B to A
Message<other_model=a, thread_user=c, posting_user=c>, # C to A again
Message<other_model=a, thread_user=b, posting_user=a>, # A to B again
Message<other_model=a, thread_user=b, posting_user=a>, # A to C
]
我想按thread_user
对它们进行分组,以便所有带有B的消息和来自C的所有消息都是分开的。理想情况下,在这样的字典中:
{
User<b>: [
Message<other_model=a, thread_user=b, posting_user=b>, # B to A
Message<other_model=a, thread_user=b, posting_user=a>, # A to B
Message<other_model=a, thread_user=b, posting_user=b>, # B to A
Message<other_model=a, thread_user=b, posting_user=a>, # A to B again
]
User<c>: [
Message<other_model=a, thread_user=c, posting_user=c>, # C to A
Message<other_model=a, thread_user=c, posting_user=c>, # C to A again
Message<other_model=a, thread_user=b, posting_user=a>, # A to C
]
}
还有一个排序元素(所以最新鲜的主题出现在最上面),但我现在并不担心这一点。
编辑:好的,所以我设法在 2n +1查询中执行此操作(其中n是链接到OtherModel实例的“线程”数):
other_model = "<a's OtherModel instance>"
tree = []
for thread in Message.objects.filter(other_model=other_model).values_list('thread_user', flat=True).distinct():
user = User.objects.get(pk=thread)
tree.append({'user':user, 'messages':Message.objects.filter(other_model=other_model, thread_user=user)})
我的问题是需要 2n +1次查询。理想情况下,我会在一个丑陋的查询中这样做。这是否像我将要获得的那样细长?
答案 0 :(得分:1)
这实际上不是分组问题。这只是一个知道任何关系 - 即从消息到用户的关系 - 自动具有向后关系的问题。所以你真正需要做的是获取线程用户列表,然后获取每个用户的消息。
不幸的是,你没有发布实际的工作模型代码,因为当你有两个从一个模型到另一个模型的ForeignKeys时,你总是需要定义一个related_name
属性,而你还没有告诉我们这是什么。我假设它是thread_user_message
。您还没有向我们展示您如何获得您感兴趣的主题或用户。所以我不得不猜测:
users = User.objects.filter(message__other_model=a)
for user in users:
print user.thread_user_message.all()
或者,您可以在模板中执行最后两行:
{% for user in users %}
{% for message in user.thread_user_message.all %}
{{ message }}
{% endfor %}
{% endfor %}