簡體   English   中英

在Django中獲取最新的不同對象

[英]Getting the latest distinct object in Django

目前,我有一個簡單的即時通訊聊天應用程序。

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發送消息,則session_id將為“ alexkyle”。

如果亞歷克斯告訴凱爾,那仍然是“ alexkyle”。 如果亞歷克斯告訴鮑勃,那將是“ alexbob”。

我進行了設置,以使session_id始終保持唯一的字母順序。 session_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')

但是,這有效! 它以字母順序發送數據,而不是按照最近的對話發送數據。 為了使用不同,我必須使用order_by。 問題是我不希望數據按字母順序排列。 我希望按照最新的談話順序進行。 我該怎么做呢?

您的最后一行應該是這樣的

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

順便說一句,史蒂夫有觀點! session_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')

嗯,設置對話ID的方式存在缺陷。 如果您有4個用戶,分別名為alex,alexb,bob和ob,則與alex和bob的對話將具有與與alexb和obb的對話相同的ID。

關於您的問題,我不確定。 您的查詢有點復雜,每個conversation_id僅要獲得一條Message ,每條Message都是該會話的最新Message (最大值(已創建))。 我確實認為您可以通過實際添加帶有updated字段的Conversation模型(該模型的主鍵也可以是用戶名的串聯)來簡化設計。 這將更容易管理,並且可能允許更便宜的查詢。

您的對話模型可以很簡單

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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM