如何在django中每次都不会命中数据库的情况下获取请求用户查询?

时间:2019-10-11 10:33:23

标签: django django-rest-framework

我构建了一些Blog API,但遇到了问题。

在序列化器中,有一个方法字段可返回用户是否喜欢该帖子的请求。问题在于,该字段每次返回帖子都会命中用户数据库,这意味着如果返回1000个帖子,则用户数据库将被命中1000次。  如何避免这种情况?第一个想法是将请求用户分配给全局变量之类的东西,但是我不知道该怎么做。

这是序列化器

class DashboardSerializer(serializers.ModelSerializer):
    image = serializers.ImageField(allow_null=True, use_url=True)
    likes_count = serializers.SerializerMethodField(read_only=True)
    tags = TagSerializer(many=True, read_only=True)
    user_has_liked = serializers.SerializerMethodField(read_only=True)
    owner = UserField(read_only=True)
    comments = CommentsField(read_only=True, many=True, source='two_latest_comments')
    comments_count = serializers.SerializerMethodField()

    class Meta:
        model = Blog
        fields = ['id', 'title', 'owner', 'likes_count', 'user_has_liked',
                  'image', 'video', 'tags', 'get_elapsed_time_after_created',
                  'comments', 'comments_count']
        ordering = ['created_at']

    def get_likes_count(self, instance):
        return instance.likes.count()

    def get_user_has_liked(self, instance):
        request = self.context.get('request')
     ***return instance.likes.filter(pk=request.user.pk).exists()***
     *******request.user.pk hits the DB.*********


    def get_comments_count(self, instance):
        return instance.comments.count()

谢谢。

1 个答案:

答案 0 :(得分:1)

在要传递给序列化程序的查询集上使用.annotateExists subqyery,然后调整字段:

序列化器调用:

    queryset = ...  # your queryset
    user_commented = Comment.objects.filter(
        blog_id=OuterRef("pk"),
        user_id=request.user.pk,
    )
    data = DashboardSerializer(instance=queryset.annotate(
        likes_count=Count("likes"),
        comments_count=Count("comments"),
        user_has_liked=Exists(user_commented),
    )

序列化器:

class DashboardSerializer(serializers.ModelSerializer):
    image = serializers.ImageField(allow_null=True, use_url=True)
    likes_count = serializers.IntegerField(read_only=True)
    tags = TagSerializer(many=True, read_only=True)
    user_has_liked = serializers.BooleanField(read_only=True)
    owner = UserField(read_only=True)
    comments = CommentsField(read_only=True, many=True, source='two_latest_comments')
    comments_count = serializers.IntegerField(read_only=True)

    class Meta:
        model = Blog
        fields = ['id', 'title', 'owner', 'likes_count', 'user_has_liked',
                  'image', 'video', 'tags', 'get_elapsed_time_after_created',
                  'comments', 'comments_count']
        ordering = ['created_at']
相关问题