有没有办法在django rest框架中为嵌套关系(嵌套序列化器class)动态指定查询集
Is there a way to dynamically specify a queryset for nested relationship (nested serializer class) in django rest framework
假设我们有两个模型:
class Chapter(models.Model):
title = models.CharField(max_length=128)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
class Post(models.Model):
title = models.CharField(max_length=128)
body = models.TextField()
is_archived = models.BooleanField(default=False)
chapter = models.ForeignKey(Chapter, on_delete=models.CASCADE)
Chapter
模型的默认 ModelViewSet
视图集:
class ChapterViewSet(viewsets.ModelViewSet):
queryset = Chapter.objects.all()
serializer_class = ChapterSerializer
关键是 ChapterSerializer
使用 PostSerializer
执行嵌套序列化以在响应中提供 post_set
键。
class PostSerializer(serializers.HyperlinkedModelSerializer):
detail_url = HyperlinkedIdentityField(view_name='post-detail', read_only=True)
class Meta:
fields = ['id', 'title', 'is_archived', 'detail_url']
model = Post
class ChapterSerializer(serializers.ModelSerializer):
post_set = PostSerializer(read_only=True, many=True)
class Meta:
model = Chapter
fields = ['id', 'title', 'owner', 'post_set']
问题是如何为这个嵌套 PostSerializer
动态指定查询集。例如,当用户发出 GET
请求时,我只想包含未存档的帖子(is_archived
字段设置为 False
),如果已完成请求的用户不是Chapter
(request.user != current_chapter.owner
) 的所有者。有什么办法可以实现吗?
您可以使用 prefetch_related to prefetch the results used by a nested serializer, this prefetch can be filtered by using a Prefetch 对象,然后这将过滤嵌套结果
class ChapterViewSet(viewsets.ModelViewSet):
queryset = Chapter.objects.all()
serializer_class = ChapterSerializer
def get_queryset(self):
queryset = super().get_queryset()
return queryset.prefetch_related(
Prefetch('post_set', queryset=Post.objects.filter(is_archived=False))
)
在get_queryset
方法中你必须动态执行预取,当前请求可以通过self.request
访问
假设我们有两个模型:
class Chapter(models.Model):
title = models.CharField(max_length=128)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
class Post(models.Model):
title = models.CharField(max_length=128)
body = models.TextField()
is_archived = models.BooleanField(default=False)
chapter = models.ForeignKey(Chapter, on_delete=models.CASCADE)
Chapter
模型的默认 ModelViewSet
视图集:
class ChapterViewSet(viewsets.ModelViewSet):
queryset = Chapter.objects.all()
serializer_class = ChapterSerializer
关键是 ChapterSerializer
使用 PostSerializer
执行嵌套序列化以在响应中提供 post_set
键。
class PostSerializer(serializers.HyperlinkedModelSerializer):
detail_url = HyperlinkedIdentityField(view_name='post-detail', read_only=True)
class Meta:
fields = ['id', 'title', 'is_archived', 'detail_url']
model = Post
class ChapterSerializer(serializers.ModelSerializer):
post_set = PostSerializer(read_only=True, many=True)
class Meta:
model = Chapter
fields = ['id', 'title', 'owner', 'post_set']
问题是如何为这个嵌套 PostSerializer
动态指定查询集。例如,当用户发出 GET
请求时,我只想包含未存档的帖子(is_archived
字段设置为 False
),如果已完成请求的用户不是Chapter
(request.user != current_chapter.owner
) 的所有者。有什么办法可以实现吗?
您可以使用 prefetch_related to prefetch the results used by a nested serializer, this prefetch can be filtered by using a Prefetch 对象,然后这将过滤嵌套结果
class ChapterViewSet(viewsets.ModelViewSet):
queryset = Chapter.objects.all()
serializer_class = ChapterSerializer
def get_queryset(self):
queryset = super().get_queryset()
return queryset.prefetch_related(
Prefetch('post_set', queryset=Post.objects.filter(is_archived=False))
)
在get_queryset
方法中你必须动态执行预取,当前请求可以通过self.request