我在正确排序来自数据库的数据时遇到麻烦。
我的设置:我正在广泛使用Django + Django Rest Framework,并使用VueJS作为前端。我有一个数据库表,其中包含带有对用户的ForeignKey
引用的消息。这些消息来自不同的联系人(电话号码),我希望能够在对话中对它们进行分组。这样,在前端,我将能够看到一个包含所有带有该phone_number
消息的对话盒,在另一个对话盒中具有不同的phone_number
等。
我希望它的排列方式是,我希望最新的对话框出现在左上角,第二个最右边,然后继续在右下角显示最近的对话框。
这是Django模型:
class Message(models.Model):
phone_number = models.CharField(max_length=100, blank=True)
phone_number_clean = models.CharField(max_length=100, blank=True)
contact_name = models.CharField(max_length=255, blank=True)
date_time = models.DateTimeField(null=True)
body = models.TextField(blank=True)
user = models.ForeignKey(User)
在我的Django Rest Framework视图文件中,我覆盖了
list()
方法,如下所示:queryset = self.filter_queryset(self.get_queryset()).order_by("date_time") # get the data ordered by date_time
serializer = self.get_serializer(queryset, many=True)
data = serializer.data
data.sort(key=itemgetter("phone_number"))
conversation_list = []
for key, group in itertools.groupby(data, lambda item: item["phone_number"]):
conversation_dict = {}
messages = [item for item in group][-50:] # Get only the last 50 messages per phone_number
conversation_dict["messages"] = messages # A list of all the messages
conversation_dict["conversation_key"] = key
conversation_list.append(conversation_dict)
return Response(conversation_list)
我正在使用
itertools.groupby()
以便按phone_number
对邮件进行分组。因此,我的理解是必须使用data.sort(key=itemgetter("phone_number"))
,因为如果groupby()
记录分散在各处,则phone_number
不起作用。不幸的是,正是data.sort()
改变了排序方式,我完全失去了原来的order_by("date_time")
排序方式。我已经尝试了很多东西。我尝试在原始呼叫之前和之后都呼叫
data.sort(key=itemgger("date_time")
。如果我以前叫它,它没有任何作用。如果在之后调用它,则会丢失phone_number
排序。我尝试将date_time
作为第二个参数传递给data.sort()
,但这没有用。我尝试了其他我现在甚至不记得的事情-没有一个产生任何结果。我已经为此工作了1.5天,但遇到了麻烦。希望您有任何想法,包括如何更好地对数据进行分组以及如何正确进行分组和
date_time
排序。万分感谢!
最佳答案
我真的需要开始某种宗教。每次我在SO上发布问题时,我都可以在30分钟内自己回答。
这是我所做的:
QuerySet现在看起来像这样:
queryset = self.filter_queryset(self.get_queryset()).order_by("phone_number_clean", "date_time")
我在
conversation_dict
循环中添加了另一个groupby()
参数:conversation_dict["last_date"] = messages[-1]["date_time"]
本质上,它只是获取该对话的最后一条消息的日期。
在
groupby
循环之后,我只需执行以下操作:conversation_list.sort(key=itemgetter("last_date"))
我得到了想要的结果。瞧!