目前我有一个简单的消息聊天应用程序。
class Person(models.Model):
user = models.OneToOneField(User, primary_key=True)
sex = models.CharField(max_length=1, null=True, blank=True)
class Message(models.Model):
sender = models.ForeignKey(Person, related_name= 'sent')
recipient = models.ForeignKey(Person, related_name = 'received')
created = models.DateTimeField(auto_now_add=True, null = True, blank = True)
message = models.CharField(max_length=500)
conversation_id = models.CharField(max_length = 90)
我使用Django Tastypie作为我的其余API。我想创建一个收件箱,类似于Facebook的收件箱,其中会话按最近的顺序排序。最近的消息对话将显示在收件箱的顶部。
“conversation_id”是发件人的用户名和收件人的用户名。
例如,如果用户Kyle向用户Alex发送消息,则conversation_id将为“alexkyle”。
如果亚历克斯给凯尔留言,它仍然是“亚历克斯”。如果亚历克斯给Bob发消息,那将是“alexbob”。
我进行了设置,以便conversation_id始终采用该唯一的字母顺序。 conversation_id是我用来区分对话的内容。
我有以下资源:
class MessageResource(ModelResource):
sender = fields.ForeignKey(PersonResource, 'sender', full =True)
recipient= fields.ForeignKey(PersonResource, 'recipient', full=True)
class Meta:
queryset = Message.objects.all()
allowed_methods = ['get']
resource_name = 'message-list'
fields = ['message', 'sender', 'recipient', 'created', 'id', 'conversation_id', 'username']
authorization = Authorization()
authentication = BasicAuthentication()
include_resource_uri = False
def get_object_list(self, request):
return super(MessageResource, self).get_object_list(request).filter(Q(sender__user = request.user) | Q(recipient__user = request.user)).distinct('conversation_id').order_by('conversation_id','-created')
但这有效!它按字母顺序发送数据,而不是最近的最新会话。为了使用distinct,我必须使用order_by。问题是我不希望数据按字母顺序排列。我希望它符合最新的对话。我怎么能这样做呢?
答案 0 :(得分:3)
你的最后一行应该是这样的
return super(MessageResource, self).get_object_list(request).filter(Q(sender__user = request.user) | Q(recipient__user = request.user)).distinct('conversation_id').annotate(last_created=MAX(created)).order_by('-last_created')
在代码中,我使用了MAX方法,该方法应该使用以下内容导入:
from django.db.models import Max
顺便说一句史蒂夫有点意思! conversation_id对我来说似乎有点问题。
更新1
要对分组使用注释,应调用values或values_list方法:
return super(MessageResource, self).get_object_list(request).filter(Q(sender__user = request.user) | Q(recipient__user = request.user)).values('conversation_id').annotate(last_created=Max(created), distinct=True).order_by('-last_created')
答案 1 :(得分:2)
嗯,你设置会话ID的方式有一个缺陷。 如果您有4个用户,名为alex,alexb,bob和ob,则与alex和bob的对话将与具有alexb和ob的用户具有相同的ID ...
关于你的问题,我不确定。您的查询有点复杂,您希望每Message
只获得一个conversation_id
,每个Message
是对话的最新版本(最大(已创建))。我确实认为你可以通过实际添加Conversation
模型(此模型的主键也可以是用户名的串联)和updated
字段来简化您的设计。它将更容易管理,并可能允许更便宜的查询。
您的对话模型可以像
一样简单class Conversation(models.Model):
id = models.CharField(primary_key=True, max_length=64, blank=False) # the primary key is a string
updated = models.DatetimeField(auto_now=True, db_index=True)