在 Django Rest Framework 中,如何限制被序列化的外键对象的数量
In Django Rest Framework, how to limit number foreign key objects being serialized
我正在序列化一个产品模型及其评论。这是我的简单代码:
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 条评论?
我在发布之前做了一些研究,但只发现了有关过滤的问题。
谢谢。
在 Product
模型上定义一个新方法,该模型 returns 具有有限数量评论的查询集。
然后将该方法作为 CommentSerializer
的来源传递给您的 ProductSerializer
。
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: 凭记忆写代码,没有测试。但应该工作。
您可以编写自定义 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
时,将调用列表序列化器。
您需要处理 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',
]
我正在序列化一个产品模型及其评论。这是我的简单代码:
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 条评论?
我在发布之前做了一些研究,但只发现了有关过滤的问题。
谢谢。
在 Product
模型上定义一个新方法,该模型 returns 具有有限数量评论的查询集。
然后将该方法作为 CommentSerializer
的来源传递给您的 ProductSerializer
。
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: 凭记忆写代码,没有测试。但应该工作。
您可以编写自定义 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
时,将调用列表序列化器。
您需要处理 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',
]