Как 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 отвечает за две основные вещи:
Сериализация - преобразование объектов python (например, экземпляра вашего класса CustomUserModel) в словарь. В основном это делается при выполнении GET-запроса, поскольку django ORM вернет вычисленный набор запросов (например, CustomUserModel.objects.all()) в виде списка объектов CustomUserModel, который нельзя напрямую превратить в JSON для возврата на фронтенд, поэтому он сначала проходит через ваш сериализатор (с помощью to_representation), чтобы превратить его в dict, сериализуемый в JSON
.Де-сериализация - преобразование ваших response.data в проверенные данные, которые могут быть использованы для создания экземпляра вашего класса CustomUserModel. В основном используется во время POST или PATCH запросов (используется метод to_internal_value в вашем сериализаторе)