Контекстно-зависимый просмотр API рендеринга в Django REST

#django #django-rest-framework

#django #django-rest-framework

Вопрос:

Существует ли простой способ создания гиперссылок в Django Rest Browsable API, но не в других визуализациях API. Чтобы было ясно, я хотел бы отображать определенные поля в виде гиперссылок при просмотре страницы через просматриваемый API, но отображать текстовый компонент только при рендеринге через JSON.

Примером этого варианта использования является отображение pk в виде списка в виде гиперссылки на подробный вид (аналогично: http://chibisov.github.io/drf-extensions/docs/#resourceurifield ) но делать это можно только при просмотре списка в режиме просмотра API. В обычном json GET я хотел бы отобразить только pk.

Я надеюсь сделать доступный для просмотра API более удобным для использования / навигации при доступе через браузер.

Имеет ли это какое-либо отношение к делу: http://www.django-rest-framework.org/api-guide/renderers#browsableapirenderer ?

В более общем плане, можно ли в любом случае установить исключения, зависящие от режима рендеринга?

Ответ №1:

Вы можете возвращать разные сериализаторы в разных контекстах, переопределяя get_serializer метод GenericAPIView или любой из его подклассов.

Что-то вроде этого было бы правильно…

 def get_serializer(self, ...):
    if self.request.accepted_renderer.format == 'api':
        # Browsable style
    else:
        # Standard style
  

Если вы закодируете это поведение как класс mixin, вы сможете легко использовать его в своих представлениях.

Комментарии:

1. На самом деле вам нужно сравнивать с форматом, отличным от 'api' HTML.

2. @AlexRothberg — Спасибо. Исправлено.

Ответ №2:

Я создал этот микс для использования serializer_class_api в режиме API:

 class SerializerAPI(object):
    def get_serializer_class(self, *args, **kwargs):
        parent = super(SerializerAPI, self).get_serializer_class(*args, **kwargs)
        if (hasattr(self.request, 'accepted_renderer') and 
          self.request.accepted_renderer.format == 'api'):
            return self.serializer_class_api
        else:
            return parent