Django Rest Framework 是否对 SerializerMethodField 执行查询

Does Django Rest Framework execute query for SerializerMethodField

我有以下 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 个 post 时,为了获取每个 post 的评论,它是否执行数据库查询?

比如我有10个posts,这个视图是不是执行了11个数据库查询? (1 个查询获取 posts,10 个查询获取序列化器中每个 post 的注释)。

是的,它确实会在您的 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.