drf——ModelSerializer、模块和包、反序列化校验源码、断言、drf之请求
django项目改名后顺利运行
1 先改文件夹名
2 改项目名
3 改 项目内的文件夹名
4 替换掉所有文件中的 drf_day04 ---》drf_day05
5 命令行中启动:python manage.py runserver
6 setting--->django--->指定项目根路径
ModelSerializer使用
ModelSerializer继承了Serializer,可以直接跟表模型建立关系
1、要序列化或者反序列化的字段,不需要写了,需要从表模型中映射出来
2、封装了 create和update方法,后期可能自己再重写这两个方法
总结:
1、写了class Meta:model=Book; fields = '__all__',自动映射表中字段,包括字段属性
2、fields = 列表 (要序列化和反序列化的字段都放在这里,表中没有的,也要注册)
3、extra_kwargs给某个字段增加字段属性(包括read_only和write_only)
4、局部钩子和全局钩子一模一样
5、一般情况下不需要重写update和create 几遍多表关联
6、可以重写字段,但一定不要写在class Meta内部
模块和包的使用(很重要)
模块与包
模块:一个py文件,被别的py文件导入使用,这个py文件称之为模块。单纯运行这个py文件称之为脚本文件。
(举例说明:s1自己点击右键运行,这个文件s1叫脚本文件。s2中,把s1引入使用,s1就叫模块)
包:一个文件夹下有__init__.py
作用:包内部的函数,类,想给外部方便使用(导入的时候路径短一些),就要再内部做注册。
模块与包的导入问题
1、导入模块有绝对导入和相对导入,绝对路径是从环境变量中开始的(py文件所在的文件夹路径要在环境变量中)
2、导入任何模块,如果使用绝对导入,都是从环境变量开始导入起。
import xx #### xx所在路径必须在环境变量
from yy import ####yy所在路径必须在环境变量中
3、脚本文件执行的路径,会自动加入环境变量中
4、相对导入,是从当前py文件开始计算的
5、以脚本运行的文件,不能使用相对导入,只能用绝对导入
反序列化校验源码分析
之前---》ser.is_valid()--->三层校验---》局部钩子和全局钩子写法是固定---》源码中规定了是要这么写---》如果不这么写,它就执行不了
首先会先去找BookSerializer中的is_valid方法,没有会去继承的父类Serializer中去找,也没有,就继续往上找,在Serializer继承的父类:BaseSerializer中找到了is_valid()方法,
分析is_valid方法源码:
-核心:self._validated_data = self.run_validation(self.initial_data)
-self是谁?序列化类的对象--》BookSerializer---》应该从根上找:BookSerializer,然后一层一层往上走,最后在Serializer类中找到了run_validation方法
然后在执行了:self.to_internal_value(data)
查找顺序
总结:
自己总结:从序列化类中找is_valid,序列化类中没有,就从它的父类找,父类的ModelSerializer中也没有,就从继承父类Serializer中找,也没有继续找,找到BaseSerializer下的is_valid,执行Serializer的run_validation,里面有局部钩子和全局钩子
只要执行序列化类对象的.is_valid就会执行 BaseSerializer的is_valid---》就会执行:self._validated_data = self.run_validation(self.initial_data)----》Serializer的run_validation---》两句重要的话:value = self.to_internal_value(data);value = self.validate(value)---》这两句话就是局部钩子和全局钩子---》局部钩子再进去看到了validate_字段名
断言
assert关键字,断定这个条件是符合的,才能往下走,如果不符合,就抛异常
# 断言 name = '彭于晏' # assert name == 'lqz', '不是lqz,不能执行了' # 用代码翻译:翻译这句话 if not name=='lqz': raise Exception("不是lqz,不能执行了") print('lqz,来了老弟')
drf之请求
请求源码分析
1、新的request视图层的方法中的request都是这个类(from rest_framework.request import Request)的对象
2、使用request.data 取请求体中的数据(之前的Json传值request.body)
3、使用request.query_params 取请求参数中的数据
4、其他属性,用起来和之前一样
-request.method 的时候---》实际上 request._request.'method'---》反射出来的
-这个类from rest_framework.request import Request没有method,他会触发这个类的__getattr__---》
5 、FILES 用起来跟之前一样,前端传入的文件在里面
魔术方法之 . 拦截
魔术方法是 以__开头 __结尾 特点是某种情况下自动触发
__init__---->类名()自动触发
__str__---->print(对象)自动触发
__getattr__: 对象.属性,如果属性不存在,会触发__getattr__
__setattr__:对象.属性=值,会触发__setattr__
有很多魔法方法---》就想看看有多少
所有的类都继承object类中的方法
例子:
class Person: def __getattr__(self, item): print(item) # 是name 这个字符串 print(type(item)) # 是name 这个字符串 return 'lqz' def __setattr__(self, key, value): print(key) print(value) # setattr(self,key,value)# 反射内部用的就是setattr 会递归 object.__setattr__(self,key,value) p = Person() # print(p.name) # 会报错 p.name='彭于晏' print(p.name)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能