[英]Django: Annotate two values of the most recent foreign key
我實際上使用的是 python 3.7 和 Django 3.0.4。
我在我的應用程序models.py 中使用這樣的簡單消息系統。
from torii.models import User
class Room(models.Model):
users = models.ManyToManyField(User,
related_name='rooms',
blank=True)
name = models.CharField(max_length=100)
class Message(models.Model):
room = models.ForeignKey(Room,
on_delete=models.CASCADE,
related_name='messages')
user = models.ForeignKey(User,
on_delete=models.CASCADE)
content = models.TextField()
date = models.DateTimeField(auto_now_add=True)
因此,當我的用戶發送消息時,我會創建一個附加到我的Room
的新Message
對象。 我想查詢給定User
所有Room
,並在我的查詢中注釋最新消息和最后一條消息的日期。
使用Max
在我的相關消息中獲取最新日期沒有問題,如下所示:
for room in Room.objects.filter(users=user).annotate(last_message_date=Max('messages__date')).order_by('-last_message_date'):
print(room.__dict__)
{'id': 7, 'name': 'room-7', 'last_message_date': datetime.datetime(2020, 3, 20, 14, 0, 2, 118190, tzinfo=<UTC>)}
{'id': 9, 'name': 'room-9', 'last_message_date': datetime.datetime(2020, 3, 8, 15, 19, 52, 343780, tzinfo=<UTC>)}
{'id': 8, 'name': 'room-8', 'last_message_date': datetime.datetime(2020, 3, 7, 17, 18, 32, 648093, tzinfo=<UTC>)}
但是我沒有找到任何方法來簡單地注釋最后一條消息的content
。 我試過Max('messages__content')
但實際上,它是按字母順序排列的消息,返回的總是相同的人......我嘗試了幾個帶有F
和Q
子查詢,但效果不佳。
如何直接用我的查詢注釋room.messages.last().content
的結果?
最后,我用解決這個問題OuterRef
和Subquery
記錄那里。
from django.db.models import Max, OuterRef, Subquery
newest = Message.objects.filter(room_id=OuterRef('pk')).order_by('-date')
for room in Room.objects.filter(users=user)
.annotate(last_message_date=Max('messages__date'),
last_message=Subquery(newest.values('content')[:1]))
.order_by('-last_message_date'):
print(r.__dict__)
據我了解,我們事先准備了Subquery
,說要使用調用子查詢的元素的id
來annotate
過濾的元素,然后按-date
排序。 所以它返回最新的元素,我們取字段content
的value
來注釋它。
這將使用數據庫的所有性能創建一個復雜但獨特的請求。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.