Как DRF де-сериализует json?

Я использую react в качестве фронтенда и django в качестве бэкенда. Я использовал fetch API для отправки POST-запроса на сервер. Данные передаются через JSON.stringify(). Этот запрос будет перехвачен представлениями в Django, и данные будут доступны в параметре request функции представления. По крайней мере, это то, что я понял. Теперь, когда я обращаюсь к request.body, я с удивлением получаю dict. Это удивительно, потому что сериализатор (который также выполняет работу по де-сериализации) еще не пришел в действие. Тогда как же он де-сериализуется автоматически? И если это как-то работает, то зачем нужно внедрять функциональность де-сериализации в сериализатор.

Код фронтенда:

export async function AuthHandler(
    task,
    data,
    root_url
) {
    task = task==="login"?`${task}/`:''
    const resp = await fetch(`${root_url}${task}`, {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
        },
        body: JSON.stringify(data), // what goes from here is string "{ }"
    });
    const respData = await resp.json();
    if (respData['token']){
        sessionStorage.setItem('token',respData['token'])

    }
    console.log(respData)
    return respData["token"];
}

Код бэкенда:

class GenericLoginView(generics.GenericAPIView):

    queryset = CustomUserModel.objects.all()
    serializer_class = UserLoginSerializer

    def post(self, request):
        token = None
        request_data = {
            "method": request.method,
            "headers": dict(request.headers),
            "body": request.data,
            "query_params": request.query_params,
            "path": request.path,
        }

        # Print the request as a dictionary
        print("Request as Dictionary:", request_data)
        print(type(request.data)) # dict
        serializer = self.serializer_class(data=request_data["body"])
        if serializer.is_valid():
            print(serializer.validated_data)
            email = serializer.validated_data["email"]
            password = serializer.validated_data["password"]
            user = authenticate(request, email=email, password=password)
            if user:
                token = Token.objects.get(user=user).key
        else:
            print(serializer.error_messages)
        return Response({"token": token})

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

Я устал проверять тип данных request.data. Кроме того, заглянул в документацию.

Хотя они и похожи, на самом деле это два разных процесса, которые служат разным целям. Причина, по которой post request.body является dict, кроется в классах DRF Parser. Они применяются до того, как запрос попадает в функцию post вашего представления. Подробнее о них вы можете прочитать здесь https://www.django-rest-framework.org/api-guide/parsers/.

В то время как класс Serializer отвечает за две основные вещи:

  1. Сериализация - преобразование объектов python (например, экземпляра вашего класса CustomUserModel) в словарь. В основном это делается при выполнении GET-запроса, поскольку django ORM вернет вычисленный набор запросов (например, CustomUserModel.objects.all()) в виде списка объектов CustomUserModel, который нельзя напрямую превратить в JSON для возврата на фронтенд, поэтому он сначала проходит через ваш сериализатор (с помощью to_representation), чтобы превратить его в dict, сериализуемый в JSON

    .
  2. Де-сериализация - преобразование ваших response.data в проверенные данные, которые могут быть использованы для создания экземпляра вашего класса CustomUserModel. В основном используется во время POST или PATCH запросов (используется метод to_internal_value в вашем сериализаторе)

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