1👍
Option 1: Order on the Django/Python layer
The items are first sorted by user_id
, and only in case of a tie, it takes the one with the latest date. But that means that you eventually get for each user a Chats
object, ordered by the user_id
.
I think here your only option is to sort it at the Django/Python level, so wrap it into a list, and sort by the date
:
from operator import attrgetter
items = list(Chats.objects.order_by('user_id', '-date').distinct('user_id'))
items.sort(key=attrgetter('date'), reverse=True)
# work with items
and then render the items
in the template.
Option 2: Annotate the User
model instead
Another option is to annotate the User
model and thus work with a QuerySet
of User
objects:
from django.db.models import Max, OuterRef, Subquery
User.objects.filter(
chats__isnull=False
).annotate(
last_date=Max('chats__date'),
last_message=Subquery(
Chat.objects.filter(user_id=OuterRef('pk')).order_by('-date').value('chat')[:1]
)
).order_by('-last_date')
Here the User
objects will have an extra attribute .last_date
with the latest date time of the object, and .last_message
with that message.
Note: It is normally better to make use of the
settings.AUTH_USER_MODEL
[Django-doc] to refer to the user model, than to use theUser
model [Django-doc] directly. For more information you can see the referencing theUser
model section of the documentation.