在Django Rest Framework中,如何限制序列化的外键对象的数量

时间:2016-07-10 06:39:09

标签: django serialization foreign-keys django-rest-framework foreign-key-relationship

我正在序列化产品模型及其评论。这是我的简单代码:

class ProductSerializer(serializers.HyperlinkedModelSerializer):
    comment_set = CommentSerializer(many=True, read_only=True)
    class Meta:
        model = Product
        fields = [
            'title',
            'comment_set'
        ]


class CommentSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Comment
        fields = [
            'text',
        ]


class Comment(models.Model):
    product = models.ForeignKey(Product, null=True, blank=True, db_index=True)


class Product(models.Model):
    title = models.CharField(max_length=50)
    ...

问题: 如果产品有很多评论。例如,500条评论。所有500个都被序列化了。

如何将结果限制为我自己选择的数量,例如100条评论?

我在发布之前做了一些研究,但只发现了有关过滤的问题。

谢谢。

3 个答案:

答案 0 :(得分:6)

Product模型上定义一个新方法,该方法返回具有有限数量注释的查询集。

然后将该方法作为CommentSerializerProductSerializer的来源传递。

class Product(models.Model):
    title = models.CharField(max_length=50)


    def less_comments(self):
        return Comment.objects.all().filter(product=self).order_by("-id")[:100]

然后在ProductSerializer

class ProductSerializer(serializers.HyperlinkedModelSerializer):
    comment_set = CommentSerializer(many=True, read_only=True, source="less_comments")

PS:从内存中写出代码,没有对它们进行测试。但应该工作。

答案 1 :(得分:3)

您可以编写自定义ListSerializer并输入CommentSerializer,然后在ProductSerializer中创建自定义字段,其源代码基于默认相关名称:

class LimitedListSerializer(serializers.ListSerializer):

    def to_representation(self, data):
        data = data.all()[:100]
        return super(FilteredListSerializer, self).to_representation(data)

class CommentSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
            list_serializer_class = LimitedListSerializer
            model = Comment
            fields = [
                'text',]

class Product(serializers.HyperlinkedModelSerializer):
    related_comments = CommentSerializer(many=True, read_only=True, source='comment_set')

当您通过many=True时,系统会调用列表serrializer。

答案 2 :(得分:2)

您希望使用CommentSerializer的查询集来控制您保留的查询集。

您可以通过覆盖get_queryset来做到这一点。例如,要针对当前用户过滤它们。请注意,我采用此示例是因为它突出显示了如何使用请求的上下文来过滤:

class CommentSerializer(serializers.HyperlinkedModelSerializer):
    def get_queryset(self):
        user = self.context['request'].user
        queryset = Comment.objects.filter(user=user)
        return queryset

    class Meta:
        model = Comment
        fields = [
            'text',
        ]