DRF的序列化【2】

news/2024/9/23 9:20:20/

【0】前提概要

【1】基于 View + JsonResponse 编写的 5 个接口:

  1. 序列化自定义处理: 你需要自己编写序列化逻辑。
  2. 处理 JSON 格式的 POST 请求数据: 从 request.body 中获取数据,并使用 json.loads() 解析成字典,然后创建相应的对象。
  3. request.POST 和 QueryDict 的区别: request.POST 返回的是 Django 的 QueryDict 对象,与真正的 Python 字典有些差别。您可以通过 request.POST.dict() 方法将其转换为纯字典。
  4. 处理 PUT 请求的数据: PUT 请求的数据不会像 POST 请求那样自动放在 request.PUT 中,您需要自己从 request.body 中提取数据,并进行必要的解析(例如,URL 编码和解码)。
  5. 禁用 CSRF 校验: 注释掉 CSRF 校验,可以在视图函数或者中间件中进行。
python">	-1 序列化需要自己做-2 post提交数据,如果是json格式,在request.POST取不到数据--》request.bodydic=json.loads(request.body) # request.body  bytes格式Book.objects.create(**dic)-3 **request.POST--->QueryDict-->跟真正字典有差距request.POST.get('name')  # {name:[lqz,justin]}request.POST['name']request.POST.getlist('name')看源码:from django.http.request import QueryDictrequest.POST.dict()--->纯字典--**-4 put请求请求体中的数据--》不会放在request.PUT-->自己从body中转--》url编码和解码django.core.handlers.wsgi.WSGIRequest-5 注释掉csrf

【2】基于 APIView + Response 编写的 5 个接口:

  1. 禁用 CSRF 校验: 可以通过在视图函数中使用 @csrf_exempt 装饰器来禁用 CSRF 校验。
  2. 使用装饰器包装视图函数: 您可以编写一个装饰器函数,在其中调用视图函数,并在装饰器中处理一些通用的逻辑,例如异常处理或者权限验证。
python">	-1 没有csrf校验了---@wrapperdef index()--------------wrapper(index)

【3】基于 APIView + Response + 序列化类 编写的 5 个接口:

  1. 编写序列化类: 您需要编写一个继承自 serializers.Serializer 的序列化类,定义需要序列化的字段。
  2. 反序列化校验: 你可以通过字段自定义校验、局部钩子或全局钩子来实现反序列化时的数据校验。
  3. 反序列化保存: 在校验通过后,可以调用序列化器的 save 方法来保存数据,可以根据 instance 的有无来判断是创建新对象还是更新现有对象。
python">	-1 序列化:写个序列化类,继承Serializer--》写字段--》在视图类中实例化得到对象--》instance,data--》ser.dataserializer.dat ---> 不是json格式字符串 ---> 字典或者列表 ---> Response ----> json格式字符串-2 反序列化校验:(从上往下)-1 字段自己的-2 局部钩子  返回值-3 全局钩子  返回值-3 反序列化保存-1 校验过后 ser.save --->修改,新增-2 序列化列中重写 create和update--》都是调用save,但是根据instance有没有决定触发create还是update

【一】全局钩子跟局部钩子

​ 全局钩子(Global Hooks)和局部钩子(Local Hooks)通常是指在软件开发中使用的两种不同类型的钩子机制。

【1】全局钩子

  • 全局钩子是在整个应用程序中生效的钩子,它们会影响应用程序的所有部分。
  • 全局钩子通常用于在应用程序启动或某个特定事件发生时执行某些操作,例如在每个 HTTP 请求处理之前或之后执行某些代码。
  • 在 Web 开发中,全局钩子通常是通过中间件(Middleware)实现的。中间件可以拦截 HTTP 请求和响应,允许开发者在处理请求之前或之后执行自定义代码。
  • 例如,在 Django 中,可以编写中间件来实现全局钩子,这些中间件可以在请求处理的不同阶段执行自定义操作,如身份验证、日志记录等。

全局钩子示例(使用 Django 中间件)

  • 在目录下创建 middleware.py

python">class RequestLoggingMiddleware:def __init__(self, get_response):self.get_response = get_responsedef __call__(self, request):# 在请求处理之前执行的代码# 记录请求信息到日志文件logger.info(f"Request: {request.method} {request.path}")response = self.get_response(request)# 在请求处理之后执行的代码return response
  • 然后,在 Django 的设置文件中注册这个中间件:

    python"># settings.pyMIDDLEWARE = [# 其他中间件...'task_api.middleware.RequestLoggingMiddleware',
    ]
    

【2】局部钩子

  • 局部钩子是针对特定组件或功能的钩子,只在特定的代码段或功能范围内生效。
  • 局部钩子通常用于在特定事件发生时执行某些定制逻辑,例如在模型保存之前或之后执行一些操作。
  • 在软件开发中,局部钩子可以通过回调函数、事件监听器或钩子函数等方式实现。
  • 例如,在 Django 的模型中,可以利用信号(Signals)实现局部钩子,通过监听模型的特定事件(如 pre_savepost_save 等),在事件发生时执行相应的操作。
python">from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from Api01.models import Bookclass BookSerializer(serializers.Serializer):name = serializers.CharField()price = serializers.IntegerField()publish = serializers.CharField()# 局部钩子# 1 数据校验第一层,字段自己校验# 2 书名不能以sb开头--》局部钩子函数--》给某个字段加限制条件def validate_name(self, name):# if name.startswith('sb'):if 'jni' in name:# 不合法,抛异常raise ValidationError('书名不能以jni开头')else:# 合法,返回原来的数据return name

小结:

​ 总的来说,全局钩子用于影响整个应用程序的行为,而局部钩子用于在特定场景下执行定制化逻辑。在设计和开发应用程序时,合理地使用全局钩子和局部钩子可以提高代码的灵活性和可维护性。

​ 对单个字段进行校验的方法是局部钩子,而对多个字段进行校验的方法是全局钩子。

【二】APIView源码执行流程

【1】执行流程

​ 当你使用 Django REST Framework 中的 APIView 类时,它提供了一个用于处理 HTTP 请求的类视图,允许你自定义逻辑来响应不同类型的请求(如 GET、POST、PUT、DELETE 等)。让我们来看一下 APIView 的源码执行流程,并结合具体示例来解释:

  1. 初始化视图类:当你定义一个继承自 APIView 的类视图时,首先会创建这个类的实例对象。在这个阶段,会执行类的初始化方法 __init__
  2. 请求分发:当有请求到达时,Django 框架会根据请求的方法(GET、POST、PUT 等)调用对应的方法处理请求。APIView 类中提供了一系列方法来处理不同类型的请求,如 get()post()put()delete() 等。
  3. 请求前处理(dispatch):在调用对应的请求处理方法之前,会先调用 dispatch() 方法进行一些通用的请求预处理操作。这个方法可以被子类重写以添加自定义的请求预处理逻辑。例如,你可以在这个方法中进行身份验证、权限检查等操作。
  4. 请求处理:根据请求的 HTTP 方法,调用对应的请求处理方法,例如 get()post()put()delete() 等。
  5. 请求后处理:在请求处理方法执行完毕后,会进行一些请求后处理操作,比如返回响应数据、设置响应头等。
  6. 返回响应:请求处理方法执行完毕后,会返回一个响应给客户端。
  7. 结束:整个请求处理过程结束。
python">	-1 请求来:BookView.as_view()(request)-->APIView的as_view--》去除了csrf--》其它跟之前一样(super.super().as_view)--->最终本质就是执行--》self.dispatch-->self 是视图类的对象--》找到APIView的dispatch-2 APIView的dispatchdef dispatch(self, request, *args, **kwargs):# 1 包装新的request--》从此后,request就是新的了request = self.initialize_request(request, *args, **kwargs)# 2 request新的request放到了self.request中了 【self是视图类的对象】self.request = requesttry:# 3 执行三大认证self.initial(request, *args, **kwargs)#self.perform_authentication(request)#self.check_permissions(request)#self.check_throttles(request) # 3 执行跟请求方式同名的方法if request.method.lower() in self.http_method_names:handler = getattr(self, request.method.lower(),self.http_method_not_allowed)else:handler = self.http_method_not_allowed# drf的Responseresponse = handler(request, *args, **kwargs)except Exception as exc:# 4 统一处理一场--》统一返回格式response = self.handle_exception(exc)self.response = self.finalize_response(request, response, *args, **kwargs)return self.response

【2】drf 配置文件之查找顺序

在apiView中使用了drf配置文件的默认配置。以下是配置的查找顺序。

python">'''方式三:查找顺序(一般就用内置的即可)1. 视图类  (局部配置)2. django settings  (全局配置) 3. drf api_settings (内置配置)
说明:
优先使用视图类中renderer_classes的配置,其次使用django项目配置文件settings中的配置,最后使用drf内置的api_settings的配置'''

django的settings中应该按照如下格式写:

python">REST_FRAMEWORK = {'DEFAULT_RENDERER_CLASSES': [    # 配置响应'rest_framework.renderers.JSONRenderer','rest_framework.renderers.TemplateHTMLRenderer',],'DEFAULT_PARSER_CLASSES': [  # 配置请求'rest_framework.parsers.JSONParser','rest_framework.parsers.FormParser','rest_framework.parsers.MultiPartParser',],
}
# 注意:所有配置都写在一个REST_FRAMEWORK里面!

【三】drf之请求

【1】APIView之请求相关配置

python"># 为什么需要进行请求相关配置?
可以定制某些CBV只能只能接收json格式,不能接收其他格式。也就是为了自定义该接口可接受编码格式。# 默认情况下
前端上传json                  request.data里面是   ---> python字典
前端上传urlencode\formdata    request.data里面是   ---> QueryDict# 方式一,在继承自APIView及其子类的的视图类中配置(局部配置)
# 总共有三个:from rest_framework.parsers import JSONParser,FormParser,MultiPartParser
class BookView(APIView):parser_classes = [JSONParser,]# 方式二:在配置文件中配置(影响所有,全局配置)-django有套默认配置,每个项目有个配置-drf有套默认配置,每个项目也有个配置---》就在django的配置文件中REST_FRAMEWORK = {'DEFAULT_PARSER_CLASSES': [# 'rest_framework.parsers.JSONParser','rest_framework.parsers.FormParser',# 'rest_framework.parsers.MultiPartParser',],
}# 方式三:全局配了1个,某个视图类想要3个,怎么配?-只需要在视图类,配置3个即可-因为:先从视图类自身找,找不到,去项目的drf配置中找,再找不到,去drf默认的配置找# 视图类方法中的request-data-__getattr__-query_params

【四】drf之响应

【1】APIView之响应相关配置

python"># 为什么要在CBV中设置响应相关配置?
因为对于drf的响应,如果使用浏览器和postman访问同一个接口,Response返回的格式是不一样的-drf做了个判断,如果是浏览器,好看一些,如果是postman只要json数据# 方式一:在视图类中写(局部配置)-两个响应类---》找---》drf的配置文件中找--》两个类-from rest_framework.renderers import JSONRenderer,BrowsableAPIRendererclass BookView(APIView):renderer_classes=[JSONRenderer,]# 方式二:在项目配置文件中写(全局配置)REST_FRAMEWORK = {'DEFAULT_RENDERER_CLASSES': ['rest_framework.renderers.JSONRenderer','rest_framework.renderers.BrowsableAPIRenderer',],
}# 方式三:使用顺序(一般就用内置的即可)1. renderer_classes2. django settings3. drf api_settings
说明:
优先使用视图类中renderer_classes的配置,其次使用django项目配置文件settings中的配置,最后使用drf内置的api_settings的配置

【2】Response对象属性

python"># drf 的Response 源码分析-from rest_framework.response import Response-视图类的方法返回时,retrun Response ,走它的__init__, init中可以传什么参数-Responses最终继承httpresponse.# Response init可以传的参数def __init__(self, data=None, status=None,template_name=None, headers=None,exception=False, content_type=None)-data:之前咱们写的ser.data  可以是字典或列表,字符串---》序列化后返回给前端---》前端在响应体中看到的就是这个 -status: http响应的状态码,默认是200,你可以改-drf在status包下,把所有http响应状态码都写了一遍,常量-from rest_framework.status import HTTP_200_OK-Response('dddd',status=status.HTTP_200_OK)-template_name:了解即可,修改响应模板的样子,BrowsableAPIRenderer定死的样子,后期公司可以自己定制-headers:响应头,http响应的响应头 示例:header={'xxx':'yyy'}-content_type :响应编码格式,一般不动# 重点:data,status,headers# 原生djagno,如何在响应头中加东西?'''四件套 render,redirect,HttpResponse,JsonResponse方法: 产生HttpResponse然后添加属性'''# 示例:obj = HttpResponse('dddd')obj['xxc'] = 'yyc'return obj响应头添加属性涉及知识 ---> 跨域 

http://www.ppmy.cn/news/1455636.html

相关文章

C语言 | Leetcode C语言题解之第60题排列序列

题目&#xff1a; 题解&#xff1a; char* getPermutation(int n, int k) {int factorial[n];factorial[0] 1;for (int i 1; i < n; i) {factorial[i] factorial[i - 1] * i;}--k;char* ans malloc(n 1);ans[n] \0;int valid[n 1];for (int i 0; i < n; i) {val…

富格林:累积经验阻挠黑幕之手

富格林认为&#xff0c;近年来现货黄金投资市场越发火热&#xff0c;许多投资新手纷纷涌入现货黄金市场中。不过&#xff0c;在这需要提醒大家的是要提防黑幕阻挠我们顺利盈利&#xff0c;选择正规可靠的平台进行开户&#xff0c;这样可以保证投资环境的安全稳定。下面富格林将…

【简洁易学】TypeScript 学习笔记

文章目录 TypeScript学习笔记一、TS简介1. 学习前提2. TypeScript是什么&#xff1f;3. TypeScript增加了什么&#xff1f; 二、TS开发环境搭建1. 下载、安装Node.js2. npm安装TypeScript3. 创建一个TS文件&#xff0c;使用tsc对TS文件进行编译 三、TS的类型1. 类型声明2. 类型…

核心代码分析

核心代码分析 下面的代码主要有两个作用 判断是否为扫描器或者密码爆破工具&#xff0c;进行交互握手&#xff0c;效果是扫描器直接爆3306弱口令。如果是直接连接&#xff0c;去读取设定好的文件&#xff0c;并写入本地保存。 这些函数用于从MySQL数据库中获取指定文件的内容…

LCR 123. 图书整理 I

刷算法题&#xff1a; 第一遍&#xff1a;1.看5分钟&#xff0c;没思路看题解 2.通过题解改进自己的解法&#xff0c;并且要写每行的注释以及自己的思路。 3.思考自己做到了题解的哪一步&#xff0c;下次怎么才能做对(总结方法) 4.整理到自己的自媒体平台。 5.再刷重复的类…

数据结构链表

数据结构链表 链表 1&#xff09;链表的概念及结构: 链表是一种物理存储结构上非连续存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的引用链接次序实现的。 2&#xff09;实际中链表的结构非常多样&#xff0c;以下情况组合起来就有8种链表结构&#xff1a; 单向、双向…

Stable Diffusion学习记录

文章目录 前言电脑配置推荐环境搭建下载地址安装步骤步骤一&#xff0c;打开下载的秋叶整合包&#xff0c;路径秋叶整合包/sd-wenui-aki步骤二&#xff0c;打开下载好的sd-webui-aki-v4.8.7解压包 Stable Diffusion软件配置&#xff0c;插件安装&#xff0c;模型下载Stable Dif…

未授权访问

未授权访问是系统对用户限制不全&#xff0c;或者无限制&#xff0c;可以让任意用户或者限制访问用户&#xff0c;访问到需要权限认证的地址。未授权访问通常是会泄露用户信息&#xff0c;系统信息。某些服务和系统中&#xff0c;未授权访问还可以执行系统命令&#xff0c;操作…