Django休息框架 - 过滤序列化器字段

Hae*_*ung 28 django django-rest-framework

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

当产品已呈现到远程客户端时,每个产品都会使用过滤后的数据.

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

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

 class Like(models.Model):
      product = models.ForeignKey(Product, related_name="likes")
Run Code Online (Sandbox Code Playgroud)

在客户端,每个喜欢的产品都用真值计算,而不是假的.

所以我尝试使用序列化程序中的以下代码.

class ProductSerializer(serializers.ModelSerializer):

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

    class Meta:
        model = Product
        fields = ('id', 'name', 'likes')
Run Code Online (Sandbox Code Playgroud)

但是,这不符合我的要求.

我该怎么办?

以下是额外的视图代码.

@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)
Run Code Online (Sandbox Code Playgroud)

mis*_*bah 58

这样的事情怎么样:

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')
Run Code Online (Sandbox Code Playgroud)

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

  • 目前的建议是删除`SerializerMethodField()`的''get_likes'`参数,因为`get_foo()`是字段`foo`的默认命名. (8认同)
  • http://www.django-rest-framework.org/api-guide/fields/#serializermethodfield (2认同)

End*_*oth 6

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

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)))
Run Code Online (Sandbox Code Playgroud)

预取只需要一个查询,与相比,可确保性能优越SerializerMethodField

  • `prefetch_lated(Prefetch(...))` 提示是一个救星!我不知道我们可以使用 `Prefetch()` 在预取本身上创建自定义过滤器,多好的事情啊!多谢!! (2认同)