1

目前我有一个简单的消息聊天应用程序。

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”。

如果亚历克斯给凯尔发消息,它仍然是“alexkyle”。如果 Alex 向 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。问题是我不希望数据按字母顺序排列。我希望它按最新对话的顺序排列。我该怎么做呢?

4

2 回答 2

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')
于 2013-11-05T21:55:31.540 回答
2

好吧,您设置对话 ID 的方式存在缺陷。如果你有 4 个用户,分别命名为 alex、alexb、bob 和 ob,那么与 alex 和 bob 的对话将具有与 alexb 和 ob 相同的 id...

关于你的问题,我不确定。您的查询有点复杂,您只想得到一个Messageper conversation_id,每个Message都是最新的对话(Max(created))。我确实认为您可以通过实际添加一个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)
于 2013-11-05T21:45:15.483 回答