1

我有以下 Django Rest Framework 序列化程序:

from rest_framework.serializers import SerializerMethodField
from posts.api.serializers import CommentSerializer

class PostSerializer(ModelSerializer):
    comments = SerializerMethodField()
    
    class Meta:
        model = Post
        fields = ('id', 'title', 'comments')

    def get_comments(self, obj):
        return CommentSerializer(obj.comments.all(), many=True).data
            

我有以下观点:

from rest_framework.views import APIView
from rest_framework.responses import Response
from posts.models import Post

class PostsAPIView(APIView):
    
    def get(request):
        posts = Post.objects.all()
        serializer = PostSerializer(posts, many=True)
        return Response(serializer.data, status=200)

所以,我的问题是,当我的序列化程序正在准备帖子的 JSON 以获取每个帖子的评论时,它是否执行数据库查询?

例如,如果我有 10 个帖子,是否在此视图中执行了 11 个数据库查询?(1 个查询获取帖子,10 个查询获取序列化程序中每个帖子的评论)。

4

1 回答 1

2

SerializerMethodField是的,它确实在您的每个实例中执行查询。

但是,您对序列化程序和 API 进行了一些小修改,这只会调用您的数据库一次。

  1. 不要SerializerMethodField用于相关字段,而是使用序列化程序本身。但它仍会调用您的数据库以获取相关数据。
class PostSerializer(ModelSerializer):
    comments = CommentSerializer(many=True)
    
    class Meta:
        model = Post
        fields = ('id', 'title', 'comments')
  1. 使用prefetch_related函数在查询集中一次获取所有相关数据:
class PostsAPIView(APIView):
    def get(request):
        # all .prefetch_related(...) after "all" or "filter"
        posts = Post.objects.all().prefetch_related('comments')
        serializer = PostSerializer(posts, many=True)
        return Response(serializer.data, status=200)

这样,您将一次获取所有数据,并且您的数据将被序列化,而无需SerializerMethodField.

于 2021-03-26T10:24:36.303 回答