django项目改名字后顺利运行、ModelSerializer使用、模块与包的使用、反序列化校验源码分析、断言、drf之请求、魔法方法之点(.)拦截

news2024/11/24 14:59:29

一 django项目改名字后顺利运行

1 先改文件夹名
2 改项目名
3 改 项目内的文件夹名
4 替换掉所有文件中的 drf_day04_02 ---》drf_day05
5 命令行中启动:python manage.py runserver
6 setting--->django--->指定项目根路径

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二 同时创建作者和作者详情表(一对一)

1.模型层

class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    sex = models.CharField(max_length=32)

    author_detail = models.OneToOneField(to="AuthorDetail", on_delete=models.CASCADE, null=True)

    # 字段的高级定制
    @property
    def author_detail_dict(self):
        return {'phone': self.author_detail.phone, 'addr': self.author_detail.addr}


class AuthorDetail(models.Model):
    phone = models.IntegerField()
    addr = models.CharField(max_length=32)

2.路由

path('author/', AuthorView.as_view()),
path('author/<int:pk>/', AuthorDetailView.as_view())

3.序列化类

class AuthorSerializer(serializers.Serializer):
    name = serializers.CharField()
    age = serializers.IntegerField()
    sex = serializers.CharField()
    # 详情表的数据
    phone = serializers.IntegerField(write_only=True)
    addr = serializers.CharField(write_only=True)

    author_detail_dict = serializers.DictField(read_only=True)

    def update(self, instance, validated_data):
        # 方式1:
        # # 首先,更新 Author 模型的字段
        # instance.name = validated_data.get('name')
        # instance.age = validated_data.get('age')
        # instance.sex = validated_data.get('sex')
        # 
        # # 然后,更新 AuthorDetail 模型的字段
        # author_detail = instance.author_detail
        # if author_detail:
        #     author_detail.phone = validated_data.get('phone')
        #     author_detail.addr = validated_data.get('addr')
        #     author_detail.save()
        # instance.save()
        # return instance

        # 方式2:
        for key in validated_data:
            setattr(instance, key, validated_data.get(key))
            setattr(instance.author_detail, key, validated_data.get(key))
        instance.save()
        instance.author_detail.save()
        return instance

    def create(self, validated_data):
        phone = validated_data.pop('phone')
        addr = validated_data.pop('addr')

        author_detail = AuthorDetail.objects.create(phone=phone, addr=addr)

        # 新增作者,可以存入 author_detail=author_detail, 也可以 author_detail_id=author_detail.pk
        author = Author.objects.create(author_detail=author_detail, **validated_data)

        return author

4.视图层

class AuthorView(APIView):
    def get(self, request, *args, **kwargs):
        author = Author.objects.all()
        ser = AuthorSerializer(instance=author, many=True)
        return Response({'code': 100, 'msg': '出版社查询成功', 'data': ser.data})

    def post(self, request, *args, **kwargs):
        ser = AuthorSerializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': '数据新增成功', 'data': ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors})


class AuthorDetailView(APIView):
    def get(self, request, pk, *args, **kwargs):
        author = Author.objects.filter(pk=pk).first()
        ser = AuthorSerializer(instance=author)
        return Response({'code': 100, 'msg': f'id为{pk}的数据查询成功', 'data': ser.data})

    def put(self,  request, pk, *args, **kwargs):
        author = Author.objects.filter(pk=pk).first()
        ser = AuthorSerializer(instance=author, data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': '数据修改成功', 'data': ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors})

    def delete(self, request, pk, *args, **kwargs):
        author = Author.objects.filter(pk=pk).first()
        author.author_detail.delete()
        author.delete()
        return Response({'code': 100, 'msg': '删除成功'})

三 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 内部
# class BookSerializer(serializers.ModelSerializer):
#     '''
#     ####### 序列化的时候#########
#      1 有的字段不想做序列化
#      2 publish 默认显示id,我们想显示详情--->重写字段,必须在fields中注册
#      3 作者显示id列表,我们想显示作者详情列表--->重写字段,必须在fields中注册
#
#     '''
#
#     class Meta:
#         model = Book
#         # fields = '__all__'  # 内部本质:把Book表模型中所有字段,都复制过来的
#         fields = ['name', 'price','publish_dict','author_list']  # 要序列化的字段
#
#     # 咱们用了方式二重写的
#     publish_dict = serializers.DictField()
#     author_list=serializers.ListField()


class BookSerializer(serializers.ModelSerializer):
    '''
    反序列化和校验
    --校验:
        1 限制name 最长不能超过8
            -方式一 :重写这个字段    不好
            -方式二:extra_kwargs传入
        2 publish_dict,author_list只做序列化,必须加read_only

        3 之前讲的局部钩子和全局钩子,完全一样

        4 可以不重写  create和update的。咱们这个案例就不用重写
            -它俩只做反序列化
                -'publish'---->不要写成publish_id,就写成表中的字段
                'authors'
    '''

    class Meta:
        model = Book
        fields = ['name', 'price', 'publish_dict', 'author_list', 'publish', 'authors']  # 要序列化的字段
        extra_kwargs = {
            'name': {'max_length': 8, 'min_length': 3},  # 等同于name=serializers.CharField(max_length=8,min_length=3)
            'publish': {'write_only': True},
            'authors': {'write_only': True}
        }

        # 只做序列化---》加 read_only

    publish_dict = serializers.DictField(read_only=True)
    author_list = serializers.ListField(read_only=True)

    # 局部钩子
    def validate_name(self, value):
        print('我走了---》', value)
        return value

四 模块与包的使用(很重要)

-模块与包
	-模块:一个py文件,被别的py文件导入使用,这个py文件称之为模块,运行的这个py文件称之为脚本文件
    	- s1自己点右键运行,这个文件s1叫脚本文件
        - 在s2中,把s1,引入使用,s1就叫模块
        
    -包:一个文件夹下有__init__.py 
    	-作用:包内部的函数,类..想给外部方便使用(导入的时候路径短一些),就要在里面做注册
        
    
    
-模块与包的导入问题
    '''
    0 导入模块有相对导入和绝对导入,绝对的路径是从环境变量开始的
    1 导入任何模块,如果使用绝对导入,都是从环境变量开始导入起  
    	import xx  #### xx所在路径必须在环境变量
        from yy  import   ####yy所在路径必须在环境变量中
        
    2 脚本文件执行的路径,会自动加入环境变量
    
    3 相对导入的话,是从当前py文件开始计算的
    
    4 以脚本运行的文件,不能使用相对导入,只能用绝对导入
    '''

五 反序列化校验源码分析(了解)

# 之前---》ser.is_valid()--->三层---》局部钩子和全局钩子写法是固定---》源码中规定了是要这么写---》如果不这么写,它就执行不了


# 看源码,为什么 局部钩子要  validate_字段名(self,value)  这么写
	-入口:ser.is_valid()
    
      def is_valid(self, *, raise_exception=False):
        # 如果 self中有_validated_data这个属性---》if就不走了
        # 只要_validated_data这个属性有,说明它之前执行过校验了,只要校验过一次,走过一次,以后就不走了
        if not hasattr(self, '_validated_data'): 
            try:
                self._validated_data = self.run_validation(self.initial_data)
            except ValidationError as exc:
                self._validated_data = {}
                self._errors = exc.detail
            else:
                self._errors = {}

        # self._errors有值,说明有错误,校验不通过
        # raise_exception 默认是false,如果传入的是True,直接抛异常
        if self._errors and raise_exception:
            raise ValidationError(self.errors)

        return not bool(self._errors)
    
 	-核心:self._validated_data = self.run_validation(self.initial_data)
    	-self是谁?序列化类的对象--》BookSerializer---》应该从根上找:BookSerializer
        
    -Serializer 的run_validation
        def run_validation(self, data=empty):
        (is_empty_value, data) = self.validate_empty_values(data)
        if is_empty_value:
            return data
		#1 局部钩子规则
        value = self.to_internal_value(data)
        try:
            #2 放在这里
            self.run_validators(value)
            
            
            # self是 BookSerializer的对象---》validate 全局钩子
            #3 全局钩子执行位置---》可以抛异常---》因为捕获了
            # value是 校验过后的数据--》而一定要返回
            value = self.validate(value)
            raise ValidationError(detail=as_serializer_error(exc))

        return value
    
    
   -执行了:self.to_internal_value(data)
	 def to_internal_value(self, data):
        for field in fields: # 序列化类中一个个字段类的对象放到列表中,每次拿出一个字段类对象
            # self 是BookSerializer的对象
            # 去BookSerializer的对象中反射    validate_字段名
            validate_method = getattr(self, 'validate_' + field.field_name, None)
            try:
                if validate_method is not None:
                    # 如果有值,就会执行局部钩子,传入待校验的数据,局部钩子必须返回数据
                    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)

        return ret


 # 总结:
	只要执行序列化类对象的.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 == 'lin', '不是lin,不能执行了'

# 用代码翻译:翻译这句话
if not name=='lin':
    raise Exception("不是lqz,不能执行了")


print('lin,来了老弟')

七 drf之请求

新的request对象

from rest_framework.request import Request


1 以后视图类的方法中的request都是这个类的对象
2 以后使用request.data  取请求体中的数据
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__
	

class Person:
    def __getattr__(self, item):
        print(item) #  是name 这个字符串
        print(type(item)) #  是name 这个字符串
        return 'lin'

    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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/959948.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ros noetic 机器人坐标记录运动路径和发布 实战教程(A)

前言: 网上记录Path的写入文件看了一下还挺多的,有用yaml作为载体文件,也有用csv文件的路径信息,也有用txt来记录当前生成的路径信息,载体不重要,反正都是记录的方式,本文主要按yaml的方式写入,后文中将补全其余两种方式。 其中两种方式的主要区别在于,加载yaml所需要…

ASUS华硕VivoBook15笔记本V5200EA_X515EA原装出厂Win11预装OEM系统

华硕11代酷睿笔记本电脑VivoBook_ASUSLaptop X515EA_V5200EA原厂Windows11系统 自带显卡、声卡、网卡、蓝牙等所有驱动、出厂主题壁纸、Office办公软件、华硕电脑管家MyASUS、迈克菲等预装程序 链接&#xff1a;https://pan.baidu.com/s/1yAEdA7aiuHK4CTdGLlSOKw?pwdo45a …

【MySQL】一文带你搞懂MySQL中的各种锁

1.概述 锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中&#xff0c;除传统的计算资&#xff08; CPU 、 RAM、 I/O &#xff09;的争用以外&#xff0c;数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致 性、有 效性是所有数据库必须解决的一个…

posexplode函数实战总结

目录 1、建表和准备数据 2、炸裂实践 3、错误炸裂方式 4、当字段类型为string&#xff0c;需要split一下 对单列array类型的字段进行炸裂时&#xff0c;可以使用lateral view explode。 对多列array类型的字段进行炸裂时&#xff0c;可以使用lateral view posexplode。 1…

命令行编译VS工程

先输入以下命令&#xff0c;因为命令出错了&#xff0c;就会弹出帮助&#xff0c;如下&#xff1a; "C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\devenv.exe" /help 反正就是Microsoft Visual Studio 的安装路径。 帮助界面如下&#xff1a…

新风机为什么会出现?

新风机之所以会出现&#xff0c;是因为人们对于室内空气质量的重视与需求。随着社会的进步和人们生活水平的提高&#xff0c;人们更加注重健康和舒适的居住环境&#xff0c;而室内空气质量是其中一个重要的方面。 空气污染问题&#xff1a;城市化进程加速&#xff0c;工业排放、…

vue3+ts+uniapp小程序端自定义日期选择器基于内置组件picker-view + 扩展组件 Popup 实现自定义日期选择及其他单列选择

vue3ts 基于内置组件picker-view 扩展组件 Popup 实现自定义日期选择及单列选择 vue3tsuniapp小程序端自定义日期选择器 1.先上效果图2.代码展示2.1 组件2.2 公共方法处理日期2.3 使用组件(全局自动导入的情况) 3.注意事项3.1refSelectDialog3.1 backgroundColor"#fff&q…

Python做数据分析更快,为什么很多人只学Excel,不学Python?

在当今信息时代&#xff0c;数据分析已经成为了各个行业不可或缺的工作内容。而在数据分析中&#xff0c;Excel一直是最常被使用的工具之一。然而&#xff0c;随着Python编程的兴起&#xff0c;越来越多的数据分析师开始转向Python进行数据分析。本文将从速度、灵活性、可视化和…

跳转语句(个人学习笔记黑马学习)

break语句 #include <iostream> using namespace std;int main() {cout << "请选择副本难度" << endl;cout << "1、普通" << endl;cout << "2、中等" << endl;cout << "3、困难" <…

gRPC-GateWay Swagger 实战

上一次我们分享了关于 gRPC-Gateway 快速实战 &#xff0c;可以查看地址来进行回顾 : 也可以查看关于 gRPC 的历史文章&#xff1a; gRPC介绍 gRPC 客户端调用服务端需要连接池吗&#xff1f; gRPC的拦截器 gRPC的认证 分享一下 gRPC- HTTP网关 I 今天主要是分享关于 gRPC-G…

zabbix安装部署

前期准备&#xff1a;安装mysql数据库和nginx 一、下载zabbix rpm -Uvh https://repo.zabbix.com/zabbix/4.4/rhel/7/x86_64/zabbix-release-4.4-1.el7.noarch.rpm yum-config-manager --enable rhel-7-server-optional-rpms yum install epel-release numactl yum install…

洞察商机,驱动创新:智能数据分析引领企业发展

“五度易链”产业大数据解决方案由产业经济、智慧招商、企业服务、数据服务四大应用解决方案组成&#xff0c;囊括了产业经济监测、产业诊断分析、企业监测预警、企业综合评估、大数据精准招商、招商智能管理、企业管理、企业培育、企业市场服务、企业金融服务、产业数据开放服…

Layer 2盛夏已至,StarkNet如何实现价值跃迁?

作者&#xff5c;Jason Jiang Layer 2概念在2023年夏天迎来爆发。Coinbase、ConsenSys等加密巨头纷纷下场&#xff0c;其部署的原生L2解决方案Base、Linea在过去两个月内相继完成主网上线&#xff1b;被誉为L2 四大天王之一的StarkNet也在夏天顺利完成“量子跃迁”升级&#x…

SQL优化案例教程0基础(小白必看)

前提准备&#xff1a;本案例准备了100W的数据进行SQL性能测试&#xff0c;数据库采用的是MySQL&#xff0c; 总共介绍了常见的14种SQL优化方式&#xff0c;每一种优化方式都进行了实打实的测试&#xff0c; 逐行讲解&#xff0c;通俗易懂&#xff01; 一、前提准备 提前准备一…

Sqoop实操案例-互联网招聘数据迁移

&#x1f947;&#x1f947;【大数据学习记录篇】-持续更新中~&#x1f947;&#x1f947; 个人主页&#xff1a;beixi 本文章收录于专栏&#xff08;点击传送&#xff09;&#xff1a;【大数据学习】 &#x1f493;&#x1f493;持续更新中&#xff0c;感谢各位前辈朋友们支持…

mybatis plus 3.4以上分页无效问题,limit一直加不上,MybatisPlusInterceptor无效

解决方案 1、已注册 Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor new MybatisPlusInterceptor();PaginationInnerInterceptor paginationInnerInterceptor new PaginationInnerInterceptor(DbType.MYSQL);paginationIn…

idea全局搜索失效,Ctrl+shift+F快捷键不起作用

方法1&#xff1a;是否与搜狗等输入法软件存在快捷键冲突&#xff0c;当然也可能是你新下载的什么软件导致的快捷键冲突导致IDEA全局搜索失效。比如下图&#xff1a; 可以改掉输入法的快捷键或者直接关闭输入法的快捷键&#xff0c;这样idea的全局搜索功能就恢复了。 方法2&…

一文掌握光模块知识,成为网络工程师的必备技能

在这个信息爆炸的时代&#xff0c;数据传输已经成为我们生活中不可或缺的一部分。而在众多的数据传输方式中&#xff0c;光纤通信以其高速、高带宽、低损耗的特点&#xff0c;成为了现代通信的主流。而在这个光纤通信的背后&#xff0c;有一个神奇的器件在默默地发挥着作用&…

qt creater11 翻译国际化教程教程:

先出效果图。 闲聊几句&#xff1a;qt这个翻译很方便&#xff0c;能直接导出项目里所有文字。 具体步骤如下&#xff1a; 在Qt中&#xff0c;我们可以使用QTranslator类来实现多语言切换。以下是一般步骤&#xff1a; 1. 在你的源代码中&#xff0c;所有需要翻译的字符串都…

每日一题——下一个排列

下一个排列 题目链接 读懂题目 要理解题目的意思&#xff0c;主要是要读懂这一句&#xff1a;整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。 我们来逐词分析&#xff1a; 其整数&#xff0c;即我们要将这个数组的数字构成一个十进制整数&#xff0c;例如数组…