首页 > 解决方案 > Django - 查询多个主键以创建模型属性列表和要返回的 uuid 的最快方法?

问题描述

所以我有一个功能应该返回一个用户的关注者列表,带有 uuid 和关注者用户名。用户用户名不是 PK 的原因是因为我正在使用放大,它返回用户 ID 的 UUID。正如您在下面看到的,我只是在查询用户的所有关注者,然后执行一个 for 循环来获取每个关注者的用户名并创建一个包含 uuid 和用户名的 dict 进入列表。我担心这会很慢。有没有更快的方法来做到这一点?

模型.py

class AbstractBaseModel(models.Model):
    uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, 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)

    class Meta:
        abstract = True
    
    def __repr__(self):
        return f'<{self.__class__.__name__} {self.uuid}>'

class User(AbstractBaseModel):
    username = models.CharField(max_length=255, unique=True)
    email = models.EmailField(max_length=255, unique=True)

class FollowUser(AbstractBaseModel):
    follower_id = models.ForeignKey(User, on_delete=models.CASCADE, related_name="follower_following")
    followee_id = models.OneToOneField(User, on_delete=models.CASCADE, related_name="followee_followed_by")

视图.py

@api_view(['GET'])
def get_followers(request, followee_id):
    try:
        followers = FollowUser.objects.filter(followee_id=followee_id).values_list('follower_id', flat=True)
        followers_list = list(followers)
        data = list()
        for follower_uuid in followers_list:
            try:
                username = User.objects.get(pk=follower_uuid).username
            except User.DoesNotExist:
                return Response(dict(error=f'follower id: {follower_uuid} does not exist in User model'), status=status.HTTP_400_BAD_REQUEST)
            data.append(dict(username = username, id = follower_uuid))
        response_data = dict(followers=data)
        return JsonResponse(response_data, status=status.HTTP_200_OK)
    except FollowUser.DoesNotExist:
        return Response(dict(error=f'followee id: {followee_id} does not exist in FollowUser model'), status=status.HTTP_400_BAD_REQUEST)

标签: pythondjango

解决方案


所以看起来你已经有了关注者的 UUID。在这种情况下,您可以通过执行in查询并通过一次调用数据库将它们全部取回,而不是循环遍历它们并为每个查询进行查询。

所以而不是

 for follower_uuid in followers_list:
        try:
            username = User.objects.get(pk=follower_uuid).username
        except User.DoesNotExist:
            return Response(dict(error=f'follower id: {follower_uuid} does not exist in User model'), status=status.HTTP_400_BAD_REQUEST)
        data.append(dict(username = username, id = follower_uuid))

也许你可以做类似的事情(你可能需要稍微调整一下以适应你的具体情况):

followers = User.objects.filter(pk__in=followers_list).values('username', 'pk')
data.extend(followers)

推荐阅读