如何根据父查询的条件更改子查询的值?

时间:2019-08-14 14:12:09

标签: django django-models django-orm

我正在制作一个Messenger应用,并跟踪每个聊天室和每个用户的未读消息。我的模型是这样的:

class Room(models.Model):
    id = models.BigAutoField(primary_key=True)

    slug = models.SlugField(unique=True, max_length=255, allow_unicode=True)
    name = models.CharField(max_length=100)
    participants = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='participants')

    def unread_messages_count(self, user):
        last_checked_message_id = Subquery(models.Message.objects.filter(
            room_listeners__receiver=user, room_listeners__room=self).values('id')[:1])
        return self.messages.filter(id__gt=last_checked_message_id).count()


class Message(models.Model):
    id = models.BigAutoField(primary_key=True)

    slug = models.SlugField(unique=True, max_length=255, allow_unicode=True)
    room = models.ForeignKey(Room, on_delete=models.CASCADE, related_name="messages")
    sender = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.SET_NULL)
    text = models.TextField(blank=True)
    created_date = models.DateTimeField(auto_now_add=True, db_index=True)


class RoomListener(models.Model):
    id = models.BigAutoField(primary_key=True)

    receiver = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='room_listeners')
    room = models.ForeignKey(Room, on_delete=models.CASCADE, related_name='room_listeners')
    last_checked_message = models.ForeignKey(Message, default=Message.objects.first, on_delete=models.PROTECT,
        related_name='room_listeners')

通过在Room模型中编写unread_messages_count()可以得到许多未读消息。另外,我希望每个用户获得一些未读消息。但是我对子查询的工作方式感到困惑。我想做这样的事情:

class User(AbstractUser, RelationshipStatus):
    id = models.BigAutoField(primary_key=True)

    def unread_messages_count
        last_checked_message_id = Subquery(models.Message.objects.filter(
            room_listeners__receiver=self).values('id'))
        return self.room_listeners.room.messages.filter(id__gt=last_checked_message_id).count()

但是我知道这是错误的...因为last_checked_message_id不会根据父查询的状态而改变。它是一个固定值。如何根据父查询的条件更改子查询的值?

0 个答案:

没有答案