Home > Net >  How to use order_by with last_added manytomanyfield?
How to use order_by with last_added manytomanyfield?

Time:08-20

Models.py

class ChatRoomId(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    created_date = models.DateTimeField(auto_now_add=True)
    

class MessageContent(models.Model):
    content = models.TextField(blank=True)
    created_date = models.DateTimeField(auto_now_add=True)
    modified_date = models.DateTimeField(auto_now=True)
    

class PersonalMessage(models.Model):
    message = models.ForeignKey(MessageContent, on_delete=models.CASCADE)
    sender = models.ForeignKey(CustomUser, on_delete=models.DO_NOTHING)


class PersonalRoom(models.Model):
    room_id = models.ForeignKey(ChatRoomId, on_delete=models.CASCADE)
    user = models.ManyToManyField(CustomUser)
    message_list = models.ManyToManyField(PersonalMessage)
    modified_date = models.DateTimeField(auto_now=True)

How to order this queryset PersonalRoom.objects.all() by the value "message__created_date" ManyToManyField last added message_list object, which is last_item = message_list.all().order_by('-message__created_date')[0].

My idea is

PersonalRoom.objects.all().order_by(
    Subquery(
        PersonalRoom.objects.get(pk=OuterRef('pk')).message_list.all().order_by('-message__created_date')[0]
    )
)

but this results in an error.

CodePudding user response:

Try reverse relationship like:

PersonalRoom.objects.all().order_by('-message_list__message__created_date')

CodePudding user response:

models.py

class PersonalRoom(models.Model):
    room_id = models.ForeignKey(ChatRoomId, on_delete=models.CASCADE)
    user = models.ManyToManyField(CustomUser)
    message_list = models.ManyToManyField(PersonalMessage)
    modified_date = models.DateTimeField(auto_now=True)

    @property
    def last_message_date(self):
        _message = self.message_list.all().order_by('-message__created_date')[0]
        _date = _message.message.created_date
        return _date

views.py

_rooms = PersonalRoom.objects.filter(user__in=[request.user], message_list__isnull=False).distinct()
sorted_rooms = sorted(_rooms, key=lambda item: item.last_message_date, reverse=True)

sorted_rooms is the reverse sorted PersonalRoom, where all the user related room models are sorted by the last added message with created date.

  • Related