Django对列进行分组记录

时间:2010-02-15 17:14:34

标签: django django-models

考虑以下模型:

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次查询。理想情况下,我会在一个丑陋的查询中这样做。这是否像我将要获得的那样细长?

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 %}