簡體   English   中英

Django:注釋最近外鍵的兩個值

[英]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')但實際上,它是按字母順序排列的消息,返回的總是相同的人......我嘗試了幾個帶有FQ子查詢,但效果不佳。

如何直接用我的查詢注釋room.messages.last().content的結果?

最后,我用解決這個問題OuterRefSubquery記錄那里

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 ,說要使用調用子查詢的元素的idannotate過濾的元素,然后按-date排序。 所以它返回最新的元素,我們取字段contentvalue來注釋它。

這將使用數據庫的所有性能創建一個復雜但獨特的請求。

暫無
暫無

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

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