我正在使用django rest框架为后端创建博客。我有一个具有“描述”文本字段的Posts模型。我想同时使用此模型来“显示所有帖子列表”和“显示单个帖子”。我不希望为博客页面发送描述字段,而只为单个帖子页面发送描述字段。这是我的代码:
发布模型:
class Posts(models.Model):
title = models.CharField(max_length=255)
subtitle = models.CharField(max_length = 255)
description = models.TextField(default = "")
发布ViewSet:
class PostsViewSet(viewsets.ModelViewSet):
serializer_class = serializers.PostsSerializer
queryset = models.Posts.objects.all()
后序列化器:
class PostsSerializer(serializers.ModelSerializer):
class Meta:
model = models.Posts
fields = '__all__'
注意:当我转到http://example.com/Posts时,我希望看到所有没有说明的帖子。但对于http://example.com/Posts/1,我需要描述以及其他字段。
答案 0 :(得分:0)
一种解决方案可能是引入两个序列化器,一个用于列表,一个用于详细信息页面。
所以它看起来像:
class PostDetailSerializer(serializers.ModelSerializer):
class Meta:
model = models.Posts
fields = '__all__'
然后我们可以将列表序列化器写为:
class PostListSerializer(PostDetailSerializer):
class Meta:
model = models.Posts
exclude = ('description', )
因此,现在如果您对PostDetailSerializer
进行自定义更改(例如,名称的呈现方式),那么这也将影响列表的序列化方式。如果我们想使两个序列化器彼此“独立”,那么我们也可以使两个序列化器没有这种继承。
然后,我们可以得出两个视图:
class PostList(generics.ListCreateAPIView):
queryset = models.Post.objects.all()
serializer_class = PostListSerializer
class RetrievePostView(generics.RetrieveAPIView):
queryset = models.Post.objects.all()
serializer_class = PostDetailSerializer
答案 1 :(得分:0)
可以通过多种方法实现
方法1::覆盖序列化程序的 __init__()
方法
class PostsSerializer(serializers.ModelSerializer):
class Meta:
model = models.Posts
fields = '__all__'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if 'view' in self.context and self.context['view'].action == 'list':
self.fields.pop('description')
您正在使用viewset
类作为视图。因此,我们可以从 .action
属性中获取specific actions
方法2::使用其他序列化程序(如@Willem Van Onsem所述)并为此调整您的 get_serializer_class()
# serializers.py
class PostDetailSerializer(serializers.ModelSerializer):
class Meta:
model = models.Posts
fields = '__all__'
class PostListSerializer(PostDetailSerializer):
class Meta:
model = models.Posts
exclude = ('description',)
# views.py
class PostsViewSet(viewsets.ModelViewSet):
serializer_class = serializers.PostsSerializer
queryset = models.Posts.objects.all()
def get_serializer_class(self):
if self.action == 'list':
return PostListSerializer
return PostDetailSerializer