如何在使用viewsets.ModelViewSet
和HyperlinkedSerializer
时为列表和详细信息视图设置不同的序列化程序?
我通过定义viewsets.ViewSet
和list
,(here's an example)来了解如何使用retrive
进行操作,但我不知道如何优雅地适应它viewsets.ModelViewSet
答案 0 :(得分:32)
我已经改编了“Django rest framework, use different serializers in the same ModelViewSet”的答案,这对我很有帮助,我希望你能找到有用的东西:
class MyModelViewSet(viewsets.MyModelViewSet):
queryset = MyModel.objects.all()
serializer_class = MyModelListSerializer
detail_serializer_class = MyModelDetailSerializer
def get_serializer_class(self):
if self.action == 'retrieve':
if hasattr(self, 'detail_serializer_class'):
return self.detail_serializer_class
return super(MyModelViewSet, self).get_serializer_class()
在这种情况下,您只需指定两个序列化程序并使用取决于操作的序列化程序。但是,这可以更加通用(对于所有操作)如下:
class MyModelViewSet(viewsets.MyModelViewSet):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
action_serializers = {
'retrieve': MyModelDetailSerializer,
'list': MyModelListSerializer,
'create': MyModelCreateSerializer
}
def get_serializer_class(self):
if hasattr(self, 'action_serializers'):
if self.action in self.action_serializers:
return self.action_serializers[self.action]
return super(MyModelViewSet, self).get_serializer_class()
答案 1 :(得分:1)
Viewsets扩展了GenericAPIView类,因此您可以使用this part of the documentation来解决您的问题。基本上,您需要的是覆盖 get_serializer_class 并根据您的请求返回不同的序列化程序。
答案 2 :(得分:0)
我为这份工作创造了这个小包装。 drf_custom_viewsets。
它有CustomSerializerViewSet
,它继承自ModelViewSet
,可让您为不同的操作设置不同的序列化程序。
答案 3 :(得分:0)
从 2021 年开始,我将采用不同的方式,更好、更通用的方法是执行以下操作:
class PlayersListViewSet(viewsets.ModelViewSet):
queryset = Player.objects.all()
serializer_class = PlayersListSerializer
http_method_names = ['get', 'post']
pagination_class = None
filter_backends = [filters.OrderingFilter]
ordering_fields = ['name']
serializer_class_by_action = {
'retrieve': PlayersDetailSerializer,
'list': PlayersListSerializer,
}
def get_serializer_class(self):
if hasattr(self, 'serializer_class_by_action'):
return self.serializer_class_by_action.get(self.action, self.serializer_class)
return super(MyModelViewSet, self).get_serializer_class()
def get_queryset(self):
queryset = Player.objects.all()
team_id = self.request.query_params.get('team', None)
if team_id:
try:
queryset = queryset.filter(team=team_id)
except ValueError:
raise exceptions.ParseError()
return queryset
这里的action
是序列化器使用的方法,list
是def list
,retrieve
是def retrieve
等等..< /p>