如何为'list'(球员/)和'细节'(球员/ {id})获得不同的结果?

时间:2016-02-10 17:47:06

标签: python django django-rest-framework django-queryset django-serializer

这是情况。我在Django REST API上有一个列表:/playerslist/

它返回了一个像这样的球员名单:

http://pastebin.com/JYA39gHT

这正是我想要的。但现在,我需要这个:

前往/playerslist/1/为我提供了不同的玩家编号1的信息。此列表仅用于列出具有基本信息的玩家。但我需要详细查看玩家,包含来自其他模型和不同序列化的信息,它必须是一个基本问题,但由于我对Django和Python一般都是新手,所以我必须误解一些东西。

这是我的Viewset:

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的文档只显示了一个例子,对我来说根本不清楚。

2 个答案:

答案 0 :(得分:3)

您可以覆盖方法retrieve(返回一个实例)或列表(显然返回列表),如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中指定它。

答案 1 :(得分:2)

当您执行“详细信息”时,可以获得不同的结果。查看,您要在执行“检索”时更改序列化程序。呼叫。我已经使用ModelViewSet的自定义mixin完成了这项工作,它需要一个特殊的" detail_serializer_class":

Display

你的观点很简单:

Runnable

此处,PlayersDetailSerializer是另一个具有您想要返回的字段的Serializer。

顺便说一句,如果你想支持团队的可选过滤,我强烈建议使用django-filter。这样您就不必担心验证等问题。安装完成后,只需将其添加到您的视图中即可:

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)

有关详细信息,请参阅the docs