我正在尝试获取每个组的最新文本
我的模特是:
class SampleMessaging(models.Model):
receiver_id = models.IntegerField()
sender_id = models.IntegerField()
message = models.TextField()
order = models.IntegerField()
如果我选择SampleGrouping.objects.all():
,这将是输出--------------------------------------------------------
id | sender_id|receiver_id| message | order
--------------------------------------------------------
1 | 1 | 1 | Hello World! | 1
2 | 1 | 1 | Hello World2! | 2
3 | 2 | 1 | Hello World3! | 1
4 | 2 | 1 | Hello World4! | 2
5 | 1 | 2 | Hello World5! | 3
6 | 1 | 3 | Hi World! | 1
7 | 1 | 3 | Hi World2! | 2
8 | 1 | 3 | H i World3! | 3
9 | 4 | 1 | Hi Hello! | 1
10 | 4 | 1 | Hi Hello2! | 2
11 | 4 | 1 | Hi Hello3! | 3
12 | 5 | 1 | Gintama 1! | 1
13 | 5 | 1 | Gintama 22! | 2
14 | 1 | 6 | Sakata 1! | 1
15 | 1 | 6 | Sakata 32! | 2
16 | 1 | 5 | Gintama 256! | 3
我需要的是一个ORM,它将导致:
---------------------------------------------------------------
id | sender_id | receiver_id | message | order
---------------------------------------------------------------
5 | 1 | 2 | Hello World5! | 3
8 | 1 | 3 | H i World3! | 3
11 | 4 | 1 | Hi Hello3! | 3
16 | 1 | 5 | Gintama 256! | 3
15 | 1 | 6 | Sakata 32! | 2
将此模型视为对话表,我想要的是显示每个用户对话的所有最新消息(按顺序确定)
答案 0 :(得分:2)
我无法想到比首先按数据分组更好的方法
from django.db.models import Max, Q
filter_data = list(SampleMessaging.objects.all().values('sender_id', 'receiver_id').annotate(order=Max('order')).distinct())
而不是将它与多个Q
objects组合,以便像这样过滤它们
在评论中修复案例
# http://stackoverflow.com/questions/39267554/filter-list-of-dicts-by-higest-value-of-dict-and-taking-reversed-values-into-acc/39267938#39267938
result = {}
for item in filter_data:
key = frozenset([item["sender_id"], item["receiver_id"]])
if key not in result or result[key]["order"] < item["order"]:
result[key] = item
qs_data = result.values()
# and now we can prepare our Q
qs_filter = Q(**qs_data[0])
for data in qs_data[1:]:
qs_filter |= Q(**data)
desired_qs = SampleMessaging.objects.filter(qs_filter)
注意:仅当您可以保证sender_id
,receiver_id
和order
的组合是唯一的时,此功能才有效。
<强>加成强> 将其包装到custom manager方法中,以便可以像
一样简单地调用它SampleMessaging.objects.latest_messages()