Django:注释最近外键的两个值

我实际上使用的是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)

因此,当我的用户发送消息时,我会创建一个附加到我的.我想查询给定的所有消息,并注释查询中最新消息的日期和最后一条消息。MessageRoomRoomUser


没有问题,在我的相关消息中获取最新的日期,如下所示: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>)}

但是我没有找到任何方法来简单地注释最后一条消息。我试过,但实际上,它是按字母顺序排列的消息,并且返回的人总是相同的......我尝试了几个子查询,但它效果不是很好。contentMax('messages__content')FQ


如何直接使用查询注释 的结果?room.messages.last().content


慕姐8265434
浏览 113回答 1
1回答

智慧大石

最后,我使用并记录在那里解决了这个问题。OuterRefSubqueryfrom django.db.models import Max, OuterRef, Subquery&nbsp;newest = Message.objects.filter(room_id=OuterRef('pk')).order_by('-date')for room in Room.objects.filter(users=user)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .annotate(last_message_date=Max('messages__date'),&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; last_message=Subquery(newest.values('content')[:1]))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .order_by('-last_message_date'):&nbsp;&nbsp; &nbsp; print(r.__dict__)根据我对行为的理解,我们事先准备说使用将子查询调用到滤子元素的元素,然后按 进行排序。因此,它返回最新的元素,我们采用 of 字段来注释它。Subqueryidannotate-datevaluecontent这将使用数据库的所有性能创建一个复杂但唯一的请求。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python