Django Rest Framework - отдельный класс сериализатора для каждого метода в представлении API на основе модели
Скажем, у меня есть простое представление Django REST Framework, которое расширяет несколько классов моделей и обслуживает все методы в одной конечной точке URL:
class UserAPIView(RetrieveAPIView, DestroyAPIView, BaseObjectAPIView):
permission_classes = (IsAuthenticated, )
serializer_class = UserSerializer
def get_serializer_class(self, *args, **kwargs):
# return different serializer depending on method??
# return UserUpdateSerializer
return UserViewSerializer
def get(self, request, *args, **kwargs):
"""
Retrieve user details
"""
# ...
return Response(data={'result': "OK"}, status=200)
def delete(self, request, pk):
"""
Delete user
"""
# ...
return Response(data={'result': "OK"}, status=200)
def put(self, request, pk):
"""
Change user
"""
# ...
return Response(data={'result': "OK"}, status=200)
Теперь мне нужно использовать разные сериализаторы для каждого метода, так как мой метод get будет использовать разные поля, чем мой put-method, пример serializers:
class UserViewSerializer(serializers.ModelSerializer):
firstname = serializers.Field(source='firstname')
lastname = serializers.Field(source='lastname')
username = serializers.Field(source='username')
class Meta:
model = User
class UserUpdateSerializer(serializers.ModelSerializer):
firstname = serializers.Field(source='firstname')
lastname = serializers.Field(source='lastname')
class Meta:
model = User
Можно ли использовать разные сериализаторы для каждого метода в представлении API на основе модели?
UPDATE:
Я знаю, как использовать разные сериализаторы внутри самих методов.
Но мне нужно получить API-интерфейс Browsable, созданный Swagger (Django module rest_framework_swagger) для извлечения разных сериализаторов для каждого метода.
Я вижу, что загрузка страницы браузера API запускает get_serializer_class, но внутри этого метода я не знаю, какой метод Swagger пытается получить для сериализатора.
Как я могу заставить rest_framework_swagger извлекать разные сериализаторы для каждого метода?
Ответы
Ответ 1
Я думаю, что для этого есть как минимум два способа:
-
Вы просто устанавливаете сериализатор, который вы хотите в каждом из ваших методов. Вот так:
def get(self, request, *args, **kwargs):
self.serializer_class = UserViewSerializer
# ...
return Response(data={'result': "OK"}, status=200)
-
Вы переопределяете метод get_Serializer_class. Вот так:
def get_serializer_class(self, *args, **kwargs):
if self.request.method == 'POST':
return UserUpdateSerializer
return UserViewSerializer
Надеюсь, что это поможет.
Ответ 2
Я полагаю, вы могли бы использовать yaml docstring для каждого метода для переопределения сериализаторов. Как:
def put(self, request, pk):
"""Change user
---
serializer: .serializers.UserUpdateSerializer
"""
# ...
return Response(data={'result': "OK"}, status=200)