[英]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.