Используйте разные сериализаторы для ввода и вывода из службы
Ресурс DRF по умолчанию ограничен принятием того же объекта, который он позже возвращает. Я хочу использовать другой сериализатор для ввода, чем вывод. Например, я хочу реализовать регистрацию пользователя, приняв имя пользователя и пароль при возврате нового пользовательского объекта. Можно ли использовать разные сериализаторы для ввода и вывода?
class UserListView(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
class ImaginarryUserInputSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('username', 'password', 'password_confirmation')
class ImaginaryUserOutputSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'registration_date')
Ответы
Ответ 1
Моя проблема в том, что я хочу иметь разные сериализаторы для ввода и вывода службы.
Достаточно просто иметь разные сериализаторы для разных методов запросов (например, что-то для ответа на запросы GET, отличные от PUT
, POST
и т.д.)
Просто переопределите get_serializer_class()
и верните другой класс сериализатора в зависимости от значения self.request.method
.
Это может быть не совсем то, что вы ищете, потому что когда вы укажете PUT или POST, вы все равно получите тот же стиль вывода, что и вы.
В этом случае вы, вероятно, просто должны просто написать представление явно, а не полагаться на стандартные представления по умолчанию, что-то в этом направлении...
class UserCreateOrListView(views.APIView):
def get(self, request, *args, **kwargs):
serializer = ImaginaryUserOutputSerializer(User.objects.all())
return Response(serializer.data)
def post(self, request, *args, **kwargs):
serializer = ImaginaryUserInputSerializer(data=request.DATA)
if serializer.is_valid():
user = serializer.save()
output_serializer = ImaginaryUserOutputSerializer(user)
return Response(output_serializer.data)
else:
return Response(serializer.errors, 400)
etc...
Также стоит расспросить список рассылки, поскольку другие пользователи могут делать что-то подобное и иметь полезные шаблоны для совместного использования.
Ответ 2
Одним из решений является TastyPie для Django, который имеет, например.:
Аналогично верно при сериализации/де-сериализации списков: Resource.alter_deserialized_list_data()
и Resource.alter_list_data_to_serialize()
.
Примечание. Но я считаю, что с Django REST Framework возможно (или будет) нечто подобное. DRF является относительно новым и недавно столкнулся с некоторыми существенными рефакторингами. Django REST Framework имеет довольно хорошее мнение в сообществе Django и, похоже, имеет проницательную команду разработчиков, поэтому, возможно, вам стоит подумать о том, чтобы спросить своих разработчиков или предложить улучшения. Конечно, если вы не найдете никакой помощи по StackOverflow (или встретите ответы от разработчиков DRF здесь).