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

У меня есть такой код, который при задании user_uuid просматривает информацию о пользователе. Все request приходят с токеном auth, который содержит uuid текущего пользователя. Если текущий пользователь запросил свой собственный профиль, то ключ is_current_user должен быть истинным, что и делается с помощью строки item['is_current_user'] = user_uuid == request.user.uuid, а затем у меня есть еще один флаг для того, чтобы определить, следует ли текущий пользователь за запрошенным пользователем, это item['is_following'] = FollowUser.objects.filter(follower=str(request.user.uuid), followee=user_uuid).exists(). Как вы можете видеть, это очень уродливые хаки, и я задался вопросом, могу ли я добавить эти значения в функцию annotate.

def get_user_info(request, user_uuid):
    try:
        query_annotated = User.objects.annotate(
            follower_count=Count('followee_id', distinct=True),
            followee_count=Count('follower_id', distinct=True)).get(pk=user_uuid)
    except User.DoesNotExist as e:
        return Response(dict(error=str(e),
                             user_message='User not found.'),
                        status=status.HTTP_404_NOT_FOUND)
    serializer = FullUserSerializer(query_annotated)
    # TODO: This is a hack the above annotation is not working
    item = serializer.data
    item['is_following'] = FollowUser.objects.filter(follower=str(request.user.uuid), followee=user_uuid).exists()
    item['is_current_user'] = user_uuid == request.user.uuid
    return Response(item, status=status.HTTP_200_OK)

Попробуйте это:

from django.db.models import Case, Exists, OuterRef, When, Value


query_annotated = User.objects.annotate(
    # ...
    is_following=Exists(
        FollowUser.objects.filter(
            follower=str(request.user.uuid), 
            followee=OuterRef("pk")
        )
    ),
    is_current_user=Case(
        When(
            pk=request.user.uuid, 
            then=Value(True)
        ),
        default=Value(False),
        output_field=BooleanField(),
    ),
).get(pk=user_uuid)

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