Django Rest framework - как обрабатывать экземпляр сериализатора?

У меня есть представление API, в котором я сначала хочу создать нового пользователя (уже работает), а затем вернуть объект нового пользователя (не работает).

views.py

@api_view(['GET',])
@authentication_classes([JSONWebTokenAuthentication])
@permission_classes([AllowAny])
def user(request):
    if request.method == 'GET':
        serializer = UserSerializer(request.user)
        return JsonResponse(serializer.data, safe=False)


@api_view(['POST'])
@permission_classes([AllowAny])
def user_create(request):
    exception_handler = UserUnavailable
    success_handler = UserCreated
    if request.method == 'POST':
        creation_serializer = CreateUserSerializer(data=request.data)
        user_serializer = UserSerializer(data=creation_serializer.instance)
        try:
            if creation_serializer.is_valid(raise_exception=True):
                creation_serializer.save()
                #print(user_serializer)
                if user_serializer.is_valid():
                    return JsonResponse({"status_code": success_handler.status_code,
                                         "default_detail": success_handler.default_detail,
                                         "default_code": success_handler.default_code,
                                         "user_object": user_serializer
                                         }, safe=False)
        except APIException:
            return JsonResponse({"status_code": exception_handler.status_code,
                                 "default_detail": exception_handler.default_detail,
                                 "default_code": exception_handler.default_code
                                 }, safe=False)

посмотрите также на мой UserSerializer здесь:

class UserSerializer(serializers.ModelSerializer):
    id = serializers.PrimaryKeyRelatedField(queryset=User.objects.all())

    class Meta:
        model = get_user_model()
        fields = ('id', 'user', 'avatar_url', 'avatar_tn_url')
        read_only_fields = ('id', 'user')

Ошибка, с которой я сталкиваюсь:

 AssertionError: Expected a `Response`, `HttpResponse` or `HttpStreamingResponse` to be returned from the view, but received a `<class 'NoneType'>`

Когда я печатаю(user_serializer), я вижу что-то вроде этого:

 UserSerializer(data=None):
     id = PrimaryKeyRelatedField(queryset=<QuerySet [<User: adasc3f4dvdvddw>, <User: dvsdvsdvsdv>, <User: Uaw3wdvdaw>, <User: pweof55>, <User: 123555>, <User: testuser48>, '...(remaining elements truncated)...']>)
     user = CharField(label='Username', read_only=True)
     avatar_url = ReadOnlyField()
     avatar_tn_url = ReadOnlyField()  Internal Server Error: /api/v1/user/create

Мне кажется, что user_serializer/ user_serializer.instance просто пуст, но почему?

Заранее спасибо

Для инициализации сериализатора экземпляром пользователя вместо

 user_serializer = UserSerializer(data=creation_serializer.instance.id)

Вы должны написать что-то вроде этого:

user_serializer = UserSerializer(instance=creation_serializer.instance)

вместо

Кроме того, вам не придется проверять объект, который уже был сохранен. А создать ответ вы должны следующим образом:

return JsonResponse({
    "status_code": success_handler.status_code,
    "default_detail": success_handler.default_detail,
    "default_code": success_handler.default_code,
    "new_user": user_serializer.data,
}, safe=False)

Но использование api_view теперь плохо. Гораздо лучше использовать ModelViewSet. Вы можете использовать что-то вроде этого:

class UserViewSet(ModelViewSet):
    serializer_class = UserSerializer
    queryset = User.objects.all()

    def get_serializer_class(self, *args, **kwargs):
        if self.action == 'create':
            return CreateUserSerializer
        return super().get_serializer_class(*args, **kwargs)

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)

        response_serializer = self.serializer_class(instance=serializer.instance)
        return Response(response_serializer.data, status=status.HTTP_201_CREATED, headers=headers)

Прошу прощения, я не тестировал это, могут быть опечатки. Вы можете прочитать о ModelViewsets больше здесь https://www.django-rest-framework.org/api-guide/viewsets/#modelviewset

Вернуться на верх