Как получить разные результаты для «list» (Players /) и «Detail» (Players /{ID})?

Вот ситуация. Я получил список в своем 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 показывает только один пример, и он мне не совсем понятен.

4 голоса | спросил Addict 10 FebruaryEurope/MoscowbWed, 10 Feb 2016 20:47:06 +0300000000pmWed, 10 Feb 2016 20:47:06 +030016 2016, 20:47:06

2 ответа


0

Вы можете переопределить методы получения (возвращая один экземпляр) или списка (очевидно, возвращая список), как показано в первом примере в 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.

ответил Matúš Bartko 12 FebruaryEurope/MoscowbFri, 12 Feb 2016 14:37:55 +0300000000pmFri, 12 Feb 2016 14:37:55 +030016 2016, 14:37:55
0

Чтобы получить другие результаты, когда вы выполняете подробный просмотр, вы хотите изменить сериализатор при выполнении вызова извлечения. Я сделал это с помощью специального миксина для ModelViewSet, который ожидает специальный «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 - это еще один сериализатор, в котором есть дополнительные поля, которые вы хотите вернуть.

Кроме того, если вы хотите поддерживать дополнительную фильтрацию по командам, я настоятельно рекомендую использовать django-filter. Таким образом, вам не нужно беспокоиться о проверке и т. Д. После установки просто добавьте это в набор:

filter_backends = (filters.OrderingFilter, filters.DjangoFilterBackend, )
filter_fields = ['team']

См. документы для получения дополнительной информации.

ответил misshapen 11 FebruaryEurope/MoscowbThu, 11 Feb 2016 00:12:17 +0300000000amThu, 11 Feb 2016 00:12:17 +030016 2016, 00:12:17

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132