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)

 

posted @ 2023-09-01 16:45  别管鱼油我了  阅读(16)  评论(0编辑  收藏  举报