Django - 注释查询是否当前用户关注查询用户
Django - annotate query for if queried user is followed by current user
所以我在下面给出了这段代码 user_uuid
我查找用户的信息。所有 request
都带有一个包含当前用户 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()
。如您所见,这些都是非常丑陋的 hack,我想知道我是否可以将这些值添加到 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)
版本 2
FullUserSerializer.py
class FullUserSerializer(serializers.ModelSerializer):
follower_count = serializers.IntegerField()
followee_count = serializers.IntegerField()
is_following = serializers.BooleanField()
is_current_user = serializers.BooleanField()
class Meta:
model = User
fields = ('uuid', 'username', 'avatar', 'created', 'follower_count',
'followee_count', 'is_current_user', 'is_following')
view.py
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),
is_following=Exists(
FollowUser.objects.filter(
follower=str(request.user.uuid),
followee=OuterRef("pk")
)
),
is_current_user=Case(
When(
pk=str(request.user.uuid),
then=Value(True)
),
default=Value(False),
output_field=BooleanField(),
),
).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(serializer.data, status=status.HTTP_200_OK)
model.py
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)
avatar = models.ImageField(upload_to=avatar_directory_path, blank=True, null=True)
@property
def avatar_url(self):
return self.avatar.url
试试这个:
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)
所以我在下面给出了这段代码 user_uuid
我查找用户的信息。所有 request
都带有一个包含当前用户 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()
。如您所见,这些都是非常丑陋的 hack,我想知道我是否可以将这些值添加到 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)
版本 2
FullUserSerializer.py
class FullUserSerializer(serializers.ModelSerializer):
follower_count = serializers.IntegerField()
followee_count = serializers.IntegerField()
is_following = serializers.BooleanField()
is_current_user = serializers.BooleanField()
class Meta:
model = User
fields = ('uuid', 'username', 'avatar', 'created', 'follower_count',
'followee_count', 'is_current_user', 'is_following')
view.py
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),
is_following=Exists(
FollowUser.objects.filter(
follower=str(request.user.uuid),
followee=OuterRef("pk")
)
),
is_current_user=Case(
When(
pk=str(request.user.uuid),
then=Value(True)
),
default=Value(False),
output_field=BooleanField(),
),
).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(serializer.data, status=status.HTTP_200_OK)
model.py
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)
avatar = models.ImageField(upload_to=avatar_directory_path, blank=True, null=True)
@property
def avatar_url(self):
return self.avatar.url
试试这个:
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)