【问题标题】:Filtering django REST results by SerializerMethodField通过 SerializerMethodField 过滤 django REST 结果
【发布时间】:2018-08-18 14:28:07
【问题描述】:

如何根据来自序列化程序的计算字段过滤结果?我试着把它当作任何其他领域,但 django 不喜欢它。

序列化器

class ImageSerializer(serializers.ModelSerializer):
    is_annotated = serializers.SerializerMethodField('has_annotation')

    class Meta:
        model = Image
        fields = '__all__'

    @staticmethod
    def has_annotation(image):
        return image.annotation_set.count() > 0

查看

class ImageViewSet(viewsets.ModelViewSet):
    serializer_class = ImageSerializer
    lookup_field = 'id'
    permission_classes = [
        Or(IsAdmin),
        IsAuthenticated
    ]

    def get_queryset(self):
        queryset = Image.objects

        is_annotated_filter = self.request.query_params.get('is_annotated', None)
        if is_annotated_filter is not None:
            queryset = queryset.filter.annotate(
                cnt=Count('annotation')).filter(cnt__gte=1)

        queryset_order = get_queryset_order(self.request)
        return queryset.order_by(queryset_order).all()

【问题讨论】:

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


    【解决方案1】:

    我想你误解了:1)序列化器 MethodField 其主要目的是只读的,并且序列化器不打算用于过滤查询集。

    我会像这样过滤它:

    from django.db.models import Count
    
    queryset.filter.annotate(
        cnt=Count('annotation_set')
    ).filter(cnt__gte=1)
    

    但是...你可以做得更好:

    1) 只需注释您的查询集,例如在您的 ViewSet 中

    from django.db.models import Count
    queryset = Image.objects.annotate(
        cnt_annotations=Count('annotation_set')
    )
    

    2) 然后在序列化程序中执行以下操作:

    @staticmethod
    def has_annotation(image):
        if hasattr(obj, 'has_annotation'):
            return bool(obj.cnt_annotations)
        else:
            return None
    

    【讨论】:

    • 当我尝试在 filter 上调用它时,我收到了 'function' object has no attribute 'annotate'。我认为你是对的,我对 SerializerMethodField 的作用感到困惑。我要做的就是根据图像是否有注释来过滤结果。
    • 先 .annotate(some_new_field=some_logic) 再调用 .filter(some_new_field=foo)
    猜你喜欢
    • 2022-11-18
    • 1970-01-01
    • 2021-06-20
    • 2016-12-21
    • 2016-08-13
    • 2015-02-14
    • 2017-12-28
    • 2018-12-04
    • 2016-01-14
    相关资源
    最近更新 更多