如何展望未来并在Django中订购查询集?

时间:2018-07-29 14:22:08

标签: django django-models django-views django-queryset

我正在开发聊天应用程序。这些模型是:

User:
name

Message:
user = ForeignKeyField(User, related_name="messages"),
message,
time

现在,数据库中只有两个用户。可以说消息对象就像:

  

msg1:user1:“你好”

     

msg2:user1:“你好吗?”

     

msg3:user2:“我很好。”

     

msg4:user1:“怎么了?”

     

msg5:user2:“没什么。”

     

msg6:user2:“嗯。”

现在我需要按顺序获取消息(比如说json):

{user1:[msg1, msg2], user2:[msg3], user1:[msg4], user2:[msg5, msg6]}

我需要在查询集中对其进行过滤,例如:

Message.objects.filter(....).order(....)

***此处使用json进行了解。

  • 这怎么办?
  • 有什么缺点吗?
  • 此后我将在模板中呈现它。因此,是否可以使用for循环在模板内订购相同的商品?

好的。如果无法在查询集中实现。然后,将以下示例作为示例模板:

<div class="chat">
  <div class="photo">
  </div>
  <div class="msg"></div>
  <div class="msg"></div>
</div>

我如何实现它:

{% for msg in msgs %}
   <div class="chat">
     <div class="photo">
     </div>
     <div class="msg">msg.message</div>
     <div class="msg">msg.message</div>//this should happen only if msg.user is same as previous msg.user
   </div>
{% endfor %}

那怎么办?我知道django的ifchanged控件。但是我无法使用它。

1 个答案:

答案 0 :(得分:1)

由于字典(在Python和JSON中都可以)仅包含键一次,因此上述含义没有多大意义。因此,您不能有两次包含user1的字典。

但是,我们可以使用一个包含2个元组的可迭代对象:一个包含user作为左边项目的元组,并在第二个消息中包含“ burst ”消息。像这样:

[
  (user1, [msg1, msg2]),
  (user2, [msg3]),
  (user1, [msg4]),
  (user2, [msg5, msg6])
]

我们可以通过在视图中添加一些处理来做到这一点。作为查询,我们首先按Messagetime进行排序,然后也提取user。接下来,我们使用itertools.groupby对每个用户进行分组,例如:

from itertools import groupby
from operator import attrgetter

qs = Message.objects.select_related('user').order_by('time')
all_msgs = [(u, list(ms)) for (u, ms) in groupby(qs, attrgetter('user'))]
return render(request, 'template.html', {'all_msgs': all_msgs})

然后在模板中,我们在2元组上渲染,然后分别在消息上渲染:

{% for user, msgs in all_msgs %}
  <div class="chat">
    <div class="photo">{{ user.photo }}
    </div>
    {% for msg in msgs %}
    <div class="msg">msg.message</div>
    {% endfor %}
  </div>
{% endfor %}

for循环中,您当然仍然必须填写数据。例如{{ user.photo }}(如果存在)。