【问题标题】:Reducing redundant codes in serializers.SerializerMethodField()减少序列化程序中的冗余代码。SerializerMethodField()
【发布时间】:2018-02-28 01:10:55
【问题描述】:

我的帖子序列化程序返回 top cmetscmets 的数量

我标记了下面的冗余代码。

class PostDetailSerializer(serializers.ModelSerializer):
    comments = serializers.SerializerMethodField()
    comment_count = serializers.SerializerMethodField()
    class Meta:
        model = Post
        fields = (
            ...
            'comments',
            'comment_count',
        )
    # showing the most recent comments
    def get_comments(self, obj):
        content_type = obj.get_content_type <<
        object_id = obj.id <<
        comments = Comment.objects.filter_by_instance(obj)[:2] <<
        return CommentSerializer(comments, many=True).data

    # showing the number of comments
    def get_comment_count(self, obj):
        content_type = obj.get_content_type <<
        object_id = obj.id <<
        comments_count =  Comment.objects.filter_by_instance(obj).count() <<
        return comments_count

它本身工作正常,但我不想在遇到 PostDetailSerializer 时查询 N x 2 行

expected output is below
    .....
    "comments": [
        {
          ...
            "content": "Edited!",
          ...  
        },
        {
            ...
            "content": "New wwaa!",
            ...
        }
    ],
    "comment_count": 4 

【问题讨论】:

    标签: django django-models django-forms django-rest-framework


    【解决方案1】:

    我认为您可以通过在帖子中预取 cmets 来最大限度地减少查询量。要尝试它,您可以尝试将视图中的查询集更改为

    Post.objects.all().prefetch_related('comment_set') 
    

    comment_set 应该是您颠倒的又名related_name(我将在下面重复使用comment_set 几次)。

    然后要使其使用预取,您可能需要更改

    Comment.objects.filter_by_instance(obj)[:2] 
    

    obj.comment_set.objects.all()[:2] 
    

    我不知道预取的内部原理,但我希望 cmets 已经使用该 obj 进行了预取,因此这不需要新的查询。

    我希望计数也可以在您使用时从预取中运行

    obj.comment_set.objects.count()
    

    有兴趣了解这是否有助于使查询倒计时!另外,请注意,在某些情况下,预取也会损害性能,网上有一些有趣的文章。

    【讨论】:

    • 预取不会有任何好处,因为对于每个方法,他执行单独的filter() 查询会导致忽略预取的数据。
    • 让我试着测试一下它的性能.. 我认为 zaidfazil 是对的
    • 是的,这就是为什么我建议不要使用 filter_by_instance 而是从预取 cmets 的对象中查询它。我非常有信心这将使您的查询倒计时。
    • 感谢您添加更多解释。刚刚接受了你的回答。你也可以试试这个问题吗?我想你也可以解决这个问题。 stackoverflow.com/questions/46340864/…
    猜你喜欢
    • 2021-12-30
    • 1970-01-01
    • 2023-01-07
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多