【问题标题】:Django - How to annotate a single Django objectDjango - 如何注释单个 Django 对象
【发布时间】:2021-12-18 00:38:22
【问题描述】:

所以 Django 有一个很酷的功能,您可以在其中注释查询集,就像您可以为查询集中的每个对象添加属性一样。例如,如果我有一个用户查询集,我可以用关注者数量对其进行注释,这是另一个具有对用户的外键引用的表。这可以通过QuerySet.annotate() 函数来完成。我想知道这对于单个 Django 对象是否可行。我有一个获取用户信息的视图函数,它给定一个唯一的用户 UUID,我返回用户表中的用户信息以及关注者和关注者的数量。一种方法是在所有关注者和关注者表中查询 uuid 并创建一个返回的字典。或者创建一个包含所有字段的序列化程序,而不是像使用查询集那样注释单个 Django 对象。可以这样做吗?

views.py

@api_view(['GET'])
def get_user_info(request, user_uuid):
    is_current_user = user_uuid == str(request.user.uuid)

    # Return all user info including # of followers and followees

models.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)

class FollowUser(AbstractSimpleModel):
    follower = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name='follower_id')
    followee = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name='followee_id')

我在views2.py 中尝试过这个,但问题是它不能正确返回头像网址。 serializer.serialize 在序列化的用户对象中将 avatar 保留为 ImageFieldFile

views2.py

@api_view(['GET'])
def get_user_info(request, user_uuid):
    is_current_user = user_uuid == str(request.user.uuid)

    if is_current_user:
        user_object = request.user
    else:
        try:
            user_object = User.objects.get(uuid=user_uuid)
        except User.DoesNotExist as e:
            return Response(dict(error=str(e),
                                 user_message='User does not exist.'),
                            status=status.HTTP_404_NOT_FOUND)

    user_dict = model_to_dict(user_object)
    user_dict['follower_count'] = len(FollowUser.objects.filter(followee=user_uuid))
    user_dict['followee_count'] = len(FollowUser.objects.filter(follower=user_uuid))
    user_dict['is_following'] = FollowUser.objects.filter(followee=user_uuid, follower=str(request.user.uuid)).exists()

    return Response(user_dict, status=status.HTTP_200_OK)

【问题讨论】:

    标签: python django


    【解决方案1】:
    @api_view(['GET'])
    def get_user_info(request, user_uuid):
        query = User.objects.filter(pk=user_uuid)
        if query.exists():
            query_annotated = query.annotate(
                follower_count=Count('followee_id', distinct=True),
                followee_count=Count('follower_id', distinct=True),
                is_following=Count('followee_id', filter=Q(follower_id=str(request.user.uuid))))
        else:
            return Response(dict(error=str('User not found.'),
                                 user_message='User not found.'),
                            status=status.HTTP_404_NOT_FOUND)
        serializer = FullUserSerializer(query_annotated[0])
        return Response(serializer.data, status=status.HTTP_200_OK)
    

    也许是一个解决方案?但是is_following 在我的测试中没有返回正确的值。

    【讨论】:

      猜你喜欢
      • 2020-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 2014-11-13
      • 2021-09-02
      • 2022-12-07
      • 1970-01-01
      相关资源
      最近更新 更多