【问题标题】:Django rest framework - filtering for serializer fieldDjango rest 框架 - 过滤序列化器字段
【发布时间】:2015-04-03 06:34:54
【问题描述】:

我对 Django REST-full 框架有疑问。

当产品渲染到远程客户端时,每个产品都会获取一个包含过滤数据的文件。

例如,模型可能是这样的。

 class Product(models.Model):
      name = models.CharField()

 class Like(models.Model):
      product = models.ForeignKey(Product, related_name="likes")

在客户端,每一个喜欢的产品都算作真值,而不是假值。

所以我尝试在序列化程序中使用以下代码。

class ProductSerializer(serializers.ModelSerializer):

    likes = serializers.PrimaryKeyRelatedField(many=True, queryset=Like.objects.filter(whether_like=True))

    class Meta:
        model = Product
        fields = ('id', 'name', 'likes')

但是,这不是我想要的。

我该怎么办?

以下是额外的视图代码。

@api_view(['GET'])
def product_list(request, user_id, format=None):

    if request.method == 'GET':
        products = Product.objects.all()
        serializer = ProductSerializer(products, many=True)

        return Response(serializer.data)

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    这样的事情怎么样:

    class ProductSerializer(serializers.ModelSerializer):
        likes = serializers.SerializerMethodField('get_likes')
    
        def get_likes(self, product):
            qs = Like.objects.filter(whether_like=True, product=product)
            serializer = LikeSerializer(instance=qs, many=True)
            return serializer.data
    
        class Meta:
            model = Product
            fields = ('id', 'name', 'likes')
    

    **LikeSerializer 为简洁而省略。希望这可以帮助。

    【讨论】:

    • 还有.. 我在哪里可以看到更多的参考资料?
    • 当前建议是删除 SerializerMethodField()'get_likes' 参数,因为 get_foo() 是字段 foo 的默认命名。
    【解决方案2】:

    您现在可以(从 Django 1.7 开始)在 DRF ViewSet 的查询集中使用 Prefetch 对象,而不是 SerializerMethodField,这会导致每个对象进行一次额外的数据库查询:

    from rest_framework import viewsets
    from django.db.models import Prefetch
    
    class ProductViewSet(viewsets.ModelViewSet):
        queryset = Product.objects.prefetch_related(Prefetch(
            'likes',
            queryset=Like.objects.filter(like=True)))
    

    预取只需要一个查询,与SerializerMethodField 相比,确保了非常优越的性能。

    【讨论】:

    • 谢谢!几天来,我一直在寻找解决这个确切问题的方法。
    • prefetch_related(Prefetch(...)) 提示是救命稻草!我不知道我们可以使用Prefetch() 在预取本身上制作自定义过滤器,真是太好了!非常感谢!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-04
    • 2016-05-14
    • 2021-02-17
    • 2014-07-30
    • 1970-01-01
    相关资源
    最近更新 更多