'list' (players/) 和 'detail' (players/{id}) 如何得到不同的结果?
How to have different results for 'list' (players/) and 'detail' (players/{id})?
情况是这样的。我在我的 Django REST API 上得到了一个列表:/playerslist/
它 returns 我是这样的球员名单:
这正是我目前想要的。但是现在,我需要这个:
Going for /playerslist/1/
给了我1号玩家的不同信息。这里的列表只是为了列出玩家的基本信息。但我需要播放器的详细视图,包含来自其他模型的信息和不同的序列化,这一定是一个基本问题,但由于我对 Django 和 Python 完全陌生,一般来说,我一定误解了一些东西。
这是我的视图集:
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']
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
我怎样才能做到这一点?我必须使用 @detail_route
才能得到类似 playerslist/1/detail
的东西吗?我已经尝试过了,但 DRF 的文档只显示了一个示例,对我来说根本不清楚。
要在执行 'detail' 视图时获得不同的结果,您需要在执行 'retrieve' 调用时更改序列化程序。我已经使用 ModelViewSet 的自定义 mixin 完成了此操作,它需要一个特殊的 "detail_serializer_class":
class DifferentDetailSerializerMixin(object):
"""
For a viewset, mix this in to use a different serializer class
for individual 'retrieve' views, different from the standard
serializer for lists.
"""
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
serializer = self.detail_serializer_class(instance, context=self.get_serializer_context())
return Response(serializer.data)
您的视图集很简单:
class PlayersListViewSet(DifferentDetailSerializerMixin, viewsets.ModelViewSet):
queryset = Player.objects.all()
serializer_class = PlayersListSerializer
detail_serializer_class = PlayersDetailSerializer
filter_backends = [filters.OrderingFilter]
ordering_fields = ['name']
在这里,PlayersDetailSerializer 是另一个序列化程序,它有更多您想要 return 的字段。
顺便说一句,如果你想支持团队的可选过滤,我强烈建议使用 django-filter。这样您就不必担心验证等问题。安装后,只需将其添加到您的视图集中即可:
filter_backends = (filters.OrderingFilter, filters.DjangoFilterBackend, )
filter_fields = ['team']
有关详细信息,请参阅 the docs。
您可以覆盖方法 retrieve(返回一个实例)或 list(显然返回列表),如 http://www.django-rest-framework.org/api-guide/viewsets/ 中的第一个示例所示。
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']
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
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
serializer = PlayerDetailSerializer(instance)
return Response(serializer.data)
其中 PlayerDetailSerializer 是另一个具有不同字段(任何你需要的)的序列化器,不需要在 serializer_class 中指定它。
情况是这样的。我在我的 Django REST API 上得到了一个列表:/playerslist/
它 returns 我是这样的球员名单:
这正是我目前想要的。但是现在,我需要这个:
Going for /playerslist/1/
给了我1号玩家的不同信息。这里的列表只是为了列出玩家的基本信息。但我需要播放器的详细视图,包含来自其他模型的信息和不同的序列化,这一定是一个基本问题,但由于我对 Django 和 Python 完全陌生,一般来说,我一定误解了一些东西。
这是我的视图集:
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']
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
我怎样才能做到这一点?我必须使用 @detail_route
才能得到类似 playerslist/1/detail
的东西吗?我已经尝试过了,但 DRF 的文档只显示了一个示例,对我来说根本不清楚。
要在执行 'detail' 视图时获得不同的结果,您需要在执行 'retrieve' 调用时更改序列化程序。我已经使用 ModelViewSet 的自定义 mixin 完成了此操作,它需要一个特殊的 "detail_serializer_class":
class DifferentDetailSerializerMixin(object):
"""
For a viewset, mix this in to use a different serializer class
for individual 'retrieve' views, different from the standard
serializer for lists.
"""
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
serializer = self.detail_serializer_class(instance, context=self.get_serializer_context())
return Response(serializer.data)
您的视图集很简单:
class PlayersListViewSet(DifferentDetailSerializerMixin, viewsets.ModelViewSet):
queryset = Player.objects.all()
serializer_class = PlayersListSerializer
detail_serializer_class = PlayersDetailSerializer
filter_backends = [filters.OrderingFilter]
ordering_fields = ['name']
在这里,PlayersDetailSerializer 是另一个序列化程序,它有更多您想要 return 的字段。
顺便说一句,如果你想支持团队的可选过滤,我强烈建议使用 django-filter。这样您就不必担心验证等问题。安装后,只需将其添加到您的视图集中即可:
filter_backends = (filters.OrderingFilter, filters.DjangoFilterBackend, )
filter_fields = ['team']
有关详细信息,请参阅 the docs。
您可以覆盖方法 retrieve(返回一个实例)或 list(显然返回列表),如 http://www.django-rest-framework.org/api-guide/viewsets/ 中的第一个示例所示。
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']
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
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
serializer = PlayerDetailSerializer(instance)
return Response(serializer.data)
其中 PlayerDetailSerializer 是另一个具有不同字段(任何你需要的)的序列化器,不需要在 serializer_class 中指定它。