【问题标题】:Does Django Rest Framework execute query for SerializerMethodFieldDjango Rest Framework 是否对 SerializerMethodField 执行查询
【发布时间】:2021-06-23 03:51:26
【问题描述】:

我有以下 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 以获取每个帖子的 cmets 时,它是否执行数据库查询?

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

【问题讨论】:

    标签: django django-rest-framework django-serializer drf-queryset


    【解决方案1】:

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

    【讨论】:

    • 它工作,谢谢
    猜你喜欢
    • 2016-05-23
    • 2021-08-01
    • 2016-07-21
    • 2016-09-25
    • 2020-04-23
    • 2019-05-12
    • 2014-09-08
    • 2019-01-07
    • 2018-10-14
    相关资源
    最近更新 更多