在 Django Rest 框架中发送没有描述的帖子列表



我正在为后端创建一个带有django rest框架的博客。 我有一个帖子模型,它有一个"描述"文本字段。我想将此模型用于"显示所有帖子的列表"和"显示单个帖子"。我不希望为博客页面发送描述字段,而只为单个帖子页面发送描述字段。这是我的代码:

帖子模型:

class Posts(models.Model):
title = models.CharField(max_length=255)
subtitle = models.CharField(max_length = 255)
description = models.TextField(default = "")

发布视图集:

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,我想要描述以及其他字段。

可以通过多种方法

实现方法-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属性中获取特定操作

方法2:使用不同的序列化程序(如Van Onsem提到的@Willem并为此调整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

解决方案可能是引入两个序列化程序,一个用于列表,一个用于详细信息页面。

因此,它可以看起来像:

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

最新更新