首页 > 编程问答 >DRF如何反序列化json?

DRF如何反序列化json?

时间:2024-07-21 12:01:28浏览次数:11  
标签:python django django-rest-framework backend documentation

我使用 React 作为前端,django 作为后端。 我使用 fetch API 向服务器发送 POST 请求。数据通过 JSON.stringify() 传递。 该请求将被 Django 中的视图拦截,数据可在视图函数的请求参数中获取。至少这是我所理解的。 现在,当我访问 request.body 时,我惊讶地得到了一个字典。令人惊讶的是,序列化器(也是反序列化的工作)尚未发挥作用。那么它是如何自动反序列化的呢?如果这以某种方式起作用,那么需要在序列化器中引入反序列化功能。

前端代码:

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 另外,还查阅了文档。


你观察到的行为是 Django REST framework (DRF) 如何处理传入请求的结果。DRF 不会等待你显式调用反序列化器来解析请求正文。相反,它会在你的视图中自动执行此操作,特别是在你访问 request.data 时。

以下是其工作原理的细分:

  1. request.body 中的原始数据: 你所言极是, request.body 包含从你的 React 前端发送的原始字节字符串。

  2. DRF 的 request.data DRF 的 APIView (你的 GenericLoginView 从中继承)具有 request 属性的自定义实现。此自定义 request 对象(通常是 rest_framework.request.Request 的实例)解析并处理传入的数据。它检查 Content-Type 标头以确定如何处理请求正文。在你的情况下,它是 application/json

  3. 自动解析: 当 DRF 遇到 application/json 时,它会使用 JSON 解析器自动将原始字节字符串反序列化为 Python 字典。这就是为什么你在访问 request.data 时会看到一个字典的原因,即使你还没有显式使用你的序列化器。

  4. 序列化器的作用: 那么你的序列化器( UserLoginSerializer )有什么作用?它用于 验证 转换 数据,而不是用于初始反序列化。当你实例化 serializer = self.serializer_class(data=request_data["body"]) 时,DRF 会检查数据是否符合你在序列化器中定义的规则(例如,字段类型、是否必需等)。如果数据有效, serializer.validated_data 将为你提供一个包含已清理和已验证数据的字典,你可以使用该字典进行身份验证。

总而言之,你不需要在 DRF 中显式反序列化 JSON 请求正文。 DRF 会自动为你处理此问题,并提供 request.data 中的解析数据。然后,你的序列化器用于验证和清理此已解析数据。

关于你的代码的一些额外说明:

  • 在你的 GenericLoginView 中,你不需要包含 request_data 字典中的所有内容。DRF 已经通过 request 对象的各种属性(例如 request.method request.headers request.query_params )提供了对此数据的访问。
  • 考虑使用 DRF 的内置身份验证和权限类来简化你的视图。有关详细信息,请参阅 DRF 文档的“身份验证”部分: https://www.django-rest-framework.org/api-guide/authentication/

希望这对你有帮助!如果还有其他问题,请告诉我。

标签:python,django,django-rest-framework,backend,documentation
From: 78767388

相关文章

  • python入门基础——新手必看
    前言随着人工智能,大数据的发展。python是当前时代最流行,可以在数据处理、web开发、人工智能等多个领域。它的语法简洁、开发效率高、可移植性强,并且可以和其他变成语言(比如C++)轻松衔接,本文主要讲述一些python的变量,基本数据类型,输入、输出,数据类型的转换,运算符等一些必需的......
  • python中逗号运算符的含义
    我理解了python中逗号运算符的简单概念。例如,x0,sigma=0,0.1表示x0=0,sigma=0.1。但我获得了一个代码,其中有一行如下所示。y,xe=np.histogram(np.random.normal(x0,sigma,1000))其中y和xe的输出如下。yOut[10]:array([3,17,58,136,216,25......
  • 【科大讯飞笔试题汇总】2024-07-20-科大讯飞秋招提前批(研发岗)-三语言题解(Cpp/Java/
    ......
  • Python - Pandas - loc vs iloc (DataFrame.loc[:,['column_name':]])
    原文链接:https://blog.csdn.net/weixin_48964486/article/details/123150832————————————————————————————————————————————————关于python数据分析常用库pandas中的DataFrame的loc和iloc取数据基本方法总结归纳及示例如下:1.......
  • 在 Python 中将 2 列的数据框转换为一系列 2 列
    我正在尝试处理一些时间序列数据,并且对pandas数据框相当陌生。我有一个包含两列的数据框,如下所示:+---+-----------------------+-------+--+||0|1||+---+-----------------------+-------+--+|1|2018-08-0223:00:00|456.8||......
  • 基于python的非平稳时间序列模型
    前言平稳时间序列指的是宽平稳时间序列,就是指时间序列的均值、方差和协方差等一二阶矩存在但不随时间改变,表现为时间的常数。若三个条件有一个不成立,那么就称该序列为非平稳时间序列。包括确定性趋势时间序列和随机性趋势时间序列。要想把非平稳的时间序列转化为平稳的时......
  • Django通过主机ip访问
    我自己一个人的课题,所以没有使用项目管理软件,也没有给被人演示过。有一天突然要演示,不再通过127.0.0.1访问,需要使用本机ip访问,此时报forbidden错误。两台机器同一局域网,能ping通,不存在子网穿透问题。解决方式:1.修改Django项目中的settings.py文件:ALLOWED_HOSTS=[]修改为A......
  • 猫头虎 Python知识点分享:pandas--read_csv()用法详解
    ......
  • 使用 Python 绘图
    我有一个.txt文件,从中找到有序对,然后使用numpy和matplotlib绘制图形。例如,这些是我的有序对:[[(4.0,0),(0,6.0)],[(6.0,0),(0,3.0)]](每个子列表代表最终图形中的一条线)图形如下所示:但我想找到两条线之间的交点。如果有更多的线,我怎样才能找到它们......
  • 用python计算形状的距离
    我想计算该图像的最小垂直距离和最大水平距离。就像线条一样。我正在尝试:_,binary_image=cv2.threshold(image,0,255,cv2.THRESH_BINARY)horizontal_distances=np.sum(binary_image==255,axis=1)max_horizontal_distance=np.max(horizontal_distance......