Django - Аннотируйте данные набора запросов к посту, если текущий пользователь "лайкнул" пост

Итак, у меня есть эта модель

model.py

class Post(models.Model):
    uuid = models.UUIDField(primary_key=True, default=generate_ulid_as_uuid, editable=False)
    created = models.DateTimeField('Created at', auto_now_add=True)
    updated_at = models.DateTimeField('Last updated at', auto_now=True, blank=True, null=True)
    creator = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name="post_creator")
    body = models.CharField(max_length=POST_MAX_LEN, validators=[MinLengthValidator(POST_MIN_LEN)])

class LikePost(AbstractSimpleModel):
    creator = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name="like_post")
    post = models.ForeignKey(Post, on_delete=models.CASCADE)

class User(AbstractDatesModel):
    uuid = models.UUIDField(primary_key=True)
    username = models.CharField(max_length=USERNAME_MAX_LEN, unique=True, validators=[
        MinLengthValidator(USERNAME_MIN_LEN)])
    created = models.DateTimeField('Created at', auto_now_add=True)
    updated_at = models.DateTimeField('Last updated at', auto_now=True, blank=True, null=True)

Потом у меня также есть этот аннотатор для возврата кучи данных вне таблицы Post

annotator.py

def query_to_full_post_data_serializer(post_query_set: QuerySet):
    query_set_annotated = post_query_set.annotate(
        creator_username=F('creator__username'),
        reply_count=Count('postreply', distinct=True),
        like_count=Count('likepost', distinct=True)
    ).prefetch_related(
        Prefetch('photo', Photo.objects.order_by('-created')),
        Prefetch('video', Video.objects.order_by('-created'))
    )
    return FullPostDataSerializer(query_set_annotated, many=True)

Я хочу вернуть поле под названием "user_liked", которое возвращает булево значение для каждого сообщения в наборе запросов, которое True если оно понравилось текущему пользователю, вошедшему в систему. Когда приходит запрос, я получаю текущего пользователя, делающего запрос, чтобы я мог получить его uuid. Я хочу использовать этот uuid для проверки того, понравилось ли пользователю сообщение в наборе запросов. Как проверить, понравился ли текущему вошедшему пользователю объект Post в наборе запросов Django?

Простите за мой предыдущий неправильный ответ.

Я довольно плохо разбираюсь в Django ORM, поэтому этот запрос может быть не самым лучшим образом оптимизирован. Вот что я придумал

Post.objects.all().annotate(liked_by_user=Q(likepost__creator=user))

Проблема в том, что он будет добавлять дубликаты для каждого найденного обратного отношения. Вот почему не следует использовать этот метод, а использовать много ко многим.

Например, при схеме "многие ко многим" это будет выглядеть так:

class User2(models.Model):
    _id = models.BigAutoField(primary_key=True)
    

class Post2(models.Model):
    _id = models.BigAutoField(primary_key=True)
    creators = models.ManyToManyField(User2)

и теперь вам нужно только

Post2.object.all().annotate(liked_by_user=Q(creator__in=[user]))

что гораздо лучше.

Вернуться на верх