DRF之请求与响应
2023-12-24 20:40:33
    		目录
一、模块与包回顾
- 模块与包 
  - 什么是模块? 
    - 一个py文件,被别的py文件导入使用,它就是模块
- 如果py文件,直接右键运行,它叫脚本文件
 
- 什么是包? 
    - 一个文件夹,下有 __init__.py ,和很多py文件,这个就是包
 
 
- 什么是模块? 
    
导入模块或包使用的规则
'''
    0 导入模块有相对导入和绝对导入,绝对的路径是从环境变量开始的
    1 导入任何模块,如果使用绝对导入,都是从环境变量开始导入起  
    	import xx  #### xx所在路径必须在环境变量
        from yy  import   ####yy所在路径必须在环境变量中
    2 脚本文件执行的路径,会自动加入环境变量
    3 相对导入的话,是从当前py文件开始计算的
    4 以脚本运行的文件,不能使用相对导入,只能用绝对导入
    5 pycharm 会把项目根路径加入到环境变量---> 离开pycharm就不行了
    6 我们看到第三方包,都是绝对导入
    	form 它自己的包名 import xx
    	下载的第三方包,都在site-package中,而site-package一定在环境变量中
'''二、反序列化校验源码分析(了解)
1 ?执行 ser.is_valid() 就会执行 反序列化的校验 --->字段自己 --> 局部钩子 ---> 全局钩子
2 ?入口是:ser.is_valid() ---> BaseSerializer 找到了
????1 自己写的BookSerializer ---> serializer.Serializer ----> BaseSerializer?
????2 源码如下
def is_valid(self, *, raise_exception=False):
    # self 是 ser对象---》自己写的BookSerializer的对象--》一开始没有
    # 一旦有了,就不执行了,优化is_valid被多次调用,只会走一次校验
    if not hasattr(self, '_validated_data'):
        try:
            # 一旦执行过,以后self中就有_validated_data
            # 接下来看self.run_validation(self.initial_data)
            self._validated_data = self.run_validation(self.initial_data)
        except ValidationError as exc:
            self._validated_data = {}
            self._errors = exc.detail
        else:
            self._errors = {}
    if self._errors and raise_exception:
        raise ValidationError(self.errors)
    return not bool(self._errors)?????3 self.run_validation(self.initial_data) ---> serializer.Serializer类的,不要按住ctrl点击,否则会进 Field 类,看错了
??????4 serializer.Serializer类的run_validation
def run_validation(self, data=empty):
    # data前端传入的--{"name":"张三","age":68}
    # value是---》前端传入的,字段自己校验通过的字典---{"name":"张三","age":68}
    value = self.to_internal_value(data) # 执行局部钩子
    try:
        self.run_validators(value) # 先不看,忽略掉
        # self 是 BookSerializer的对象,如果我们写了全局钩子,走我们自己的,如果没写,走父类的,父类    的根本没做校验
        # value={"name":"张三","age":68}
        value = self.validate(value)# 执行全局钩子
    except (ValidationError, DjangoValidationError) as exc:
        raise ValidationError(detail=as_serializer_error(exc))
    return value??????5 全局钩子读完了:self 是 BookSerializer的对象,如果我们写了全局钩子,走我们自己的,如果没写,走父类的,父类的根本没做校验
 ? ? ? 6 局部钩子:value = self.to_internal_value(data)--》Serializer类的
 ? ? ? ? ?for循环着去BookSerializer的对象中反射 ?validate_字段名的方法,如果有就执行,没有就不执行
def to_internal_value(self, data):
    for field in fields: # 序列化类中所有字段类的对象 name=CharField()
    # self 是BookSerializer类的对象
    # 去BookSerializer类中,反射  validate_field字段类的对象.field_name
    validate_method = getattr(self, 'validate_' + field.field_name, None)
    try:
        # 如果能拿到,说明咱么写了局部钩子
        if validate_method is not None:
        # 执行局部钩子--》传入了当前字段的value值
            validated_value = validate_method(validated_value)
    except ValidationError as exc:
        # 如果抛异常,会被捕获
        errors[field.field_name] = exc.detail
    except DjangoValidationError as exc:
        errors[field.field_name] = get_error_detail(exc)
    except SkipField:
        pass
    else:
        set_value(ret, field.source_attrs, validated_value)
    if errors:
        raise ValidationError(errors)
    return ret
##### 读了局部和全局钩子的执行位置 #####
"保存,修改也好,都要用validated_data,它是最准确的"三、断言
a = 10
# assert 后写条件,只要不符合条件,就会抛AssertionError异常,后面写异常信息
assert a == 11, ("不等于11,报错了")
# 等同于--->上面只要一行代码,源码中喜欢用
if not a == 11:
    raise Exception('不等于11,报错了')
    
    
   
# 源码中使用
assert value is not None, '.validate() should return the validated data'四、drf之请求
# Request 类的对象
from rest_framework.request import Request【1】源码分析
1 新的request
2 request.data  前端传入的请求体中得数据,无论那种编码
3 用起来跟之前一样
4 老的request在request._request【2】配置视图类能处理的编码格式
# 默认,视图类的方法,可以处理任意编码格式
	-urlencoded
    -form-data
    -json
    
# 比如有的接口,只能接收json格式,其他格式都不能处理
# 配置方式一:视图类上配置
from rest_framework.parsers import JSONParser, FormParser, MultiPartParser
# JSONParser:json
# FormParser:urlencoded
# MultiPartParser:form-data
class TestView(APIView):
    # parser_classes = [JSONParser]
    parser_classes = [JSONParser,FormParser]
    def post(self, request):
        print(request.data)
        return Response('ok')# 配置方式二:settings.py  配置文件中配置
	## 所有drf的配置,都要写在REST_FRAMEWORK字典中 ##
    REST_FRAMEWORK = {
        'DEFAULT_PARSER_CLASSES': [
            # 'rest_framework.parsers.JSONParser',
            # 'rest_framework.parsers.FormParser',
            'rest_framework.parsers.MultiPartParser',
        ],
    }
    
    
# 全局使用某种,单某个视图类,局部使用---> 优先用视图类配置的---> 视图类没配置--> 项目配置文件  ---> 项目配置文件如果没配置---> drf配置文件(默认三个都支持)
	-配置文件正常写
    class TestView(APIView):
        parser_classes = [JSONParser,FormParser]
        
        
        
# 一般我们做---> 只支持json
# 对于上传的文件的接口---》单独配置 只允许 form-data五、drf之响应
from rest_framework.response import Response【1】源码
data=None  # 咱们给的字典或列表或字符串---> 最终放到了http响应体中返回了
status=None # http响应状态码,默认是200,你可以改,改成from rest_framework import status 状态码 
"http响应状态码分别代表啥意思:200成功   201创建成功"
template_name=None:用浏览器访问好看的页面--> 指定的--> 默认使用drf提供的--> 后期可以自己写页面,使用 
headers=None, # 响应头
content_type=None # 响应编码格式
"""我们需要记住的
data
status
headers
"""【2】响应编码格式
# 配置方式跟请求解析类似
# 方式一:在视图类上配置
class TestView(APIView):
    renderer_classes = [JSONRenderer,BrowsableAPIRenderer]
# 方式二:配置文件中配置
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ],
}
# 优先用 视图类的---> 项目配置文件---> drf内置的(两个都支持)
    			文章来源:https://blog.csdn.net/qq_53842456/article/details/135185225
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
    	本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!