千锋Flask学习笔记
千锋Flask学习笔记
目录写在前面
-
学习链接:Python 900集(学完可就业/2019版):
[359集: 451集],共93集
-
感想 | 摘抄
- filter和filter_by区别:
- 接收的参数类型不一样
- cls.query.filter(类名.属性名 条件操作符 条件) 过滤特定条件,返回的是query对象
- cls.query.filter_by(关键字参数对) 单条件查询,条件必须关键字参数,而且and连接
- filter和filter_by区别:
-
学习时遇到的问题
-
Flask用pycharm启动的时候无法按代码中的设置启动(debug设置为True也没辙)
-
开发模式的环境配置在wsl的ubuntu中,bashrc和zshrc设置FLASK_ENV都没用,只有在windows的系统环境中配置了才有用
-
使用
python manage.py db init
没有迁移数据库,而是启动了服务器,并且还没有启动debug答:注意你
manage.py
中的主程序,是app不是manager吧憨憨~ -
在使用sqlalchemy的order_by的时候报错:
sqlalchemy.exc.CompileError: Can't resolve label reference for ORDER BY ...
答:这里需要给
-id
加上一个text函数Customer.query.order_by(text(-id)).first().id
-
更换flask为0.13.1之后报错:
ImportError: cannot import name 'import_string'
答:werkzeug版本兼容问题,安装
pip install werkzeug==0.15.2
就行了
-
1. Flask介绍
-
Flask是一个基于Python实现的Web开发 “微”框架
-
Flask跟Django一样,也是一个基于MVC设计模式的Web框架
-
Flask依赖三个库:
- Jinja2 模板引擎
- Werkzeub WSGI工具集
- Itsdangerous 基于Django的签名模块
-
参数配置:在启动的时候还可以添加参数,在run()中:
- debug:是否开启调试模式,开启后修改过python代码会自动重启
- threaded:是否开启多线程
- port:启动指定服务器的端口号
- host:主机,默认是127.0.0.1,指定为0.0.0.0代表本机所有ip
-
debugger:
- Flask中调试器拥有保护功能
- PIN
- 如果需要在页面中进行调试,需要输入PIN码进行确认
-
Linux
- 环境变量
- 系统级
- /etc/environment
- /etc/profile
- 用户级
- ~/.bashrc
- 临时级
- 在窗口中直接export
- 系统级
- 环境变量
-
Flask-Script
- 可以添加Flask脚本的扩展库
- 添加命令行参数
- 使用
- 安装:pip install flask-script
- 初始化:使用app构建Manager对象
- 调用:
- runserver
- -d:调试模式
- -r:自动重试加载
- -p:port(
0.0.0.0
代表所有端口) - -h:host
- --threaded:开启多线程模式
- shell
- runserver
-
简单的一阶程度拆分
-
路由的管理
- 使用的时候容易出现循环应用的问题
- 使用懒加载的方式
- 使用函数调用的形式进行加载
- 使用新方案解决
- 蓝图
- 代表的一种规划
- 路由的规划
- 蓝图
- flask-blueprint
- 使用过程
- 安装
- pip install flask-blueprint
- 初始化
- 需要创建蓝图对象
- name
- 导入名字
__name__
- 需要使用app进行初始化
- 注册在App上
- 需要创建蓝图对象
- 使用
- 和Flask对象差不多
- 直接作为装饰器用来注册路由
- 安装
- 使用过程
-
数据库
- Web开发中,大多数情况使用的都是关系型数据库
- ORM
- SQLAlchemy
- flask-sqlalchemy
- 使用过程
- 安装
pip install flask-sqlalchemy
- 初始化
- 需要使用app进行SQLAlchemy对象的创建
- 使用懒加载方式 init_app 方法搞定
- SQLALCHEMY_DATABASE_URI
- 连接数据库的路径
- URI格式
- 数据库+驱动://用户名:密码@主机:端口/库
- SQLALCHEMY_TRACK_MODIFICATIONS
- 将来被添加进来的一个特性
- 默认是False
- 需要使用app进行SQLAlchemy对象的创建
- 使用
- 定制模型
- 继承自Model
- 创建字段
- 创建库,创建表
- 库需要手动创建
- 表
- SQLAlchemy对象.create_all
- 删除 .drop_all
- 不能差量更新
- 数据操作
- 存储
- 创建对象
- SQLAlchemy对象.session.add()
- 添加完成还要进行commit()
- 存储
- 定制模型
- 安装
- 使用过程
- Flask-Migrate
- 迁移插件
- 在FLask中像Django中一样进行模型迁移
- 使用流程
- 安装
- pip install flask-migrate
- 初始化
- 使用app和db进行初始化
- 可以使用懒加载方式
- 使用
- flask db 指令
- init
- migrate
- upgrade
- 结合flask-script使用
- 在manager添加一个管理指令
- manager.add_command('db', MigrateCommand)
- python manage db 指令
- 在manager添加一个管理指令
- flask db 指令
- 安装
-
二阶拆分
-
公司开发环境
- 开发环境
- 开发人员使用
- 测试环境
- 测试人员使用
- 演示环境
- 给产品看的
- 做演习、彩排
- 生产环境、线上环境
- 真实环境
- 给用户看的
- 开发环境
-
项目结构
- 原版
- HelloFlask.py
- 改良
- 三阶改装
- manage.py
- 项目管理文件
- App
__init__
- 初始化文件
- 天然的单例
- 调用的顺序是最高的
- settings
- config
- 全局项目配置
- ext
- extension 扩展库
- 除了和路由相关
- views
- apis
- 路由,视图函数
- models
- 定制模型
- 原版
-
ODOO
- 比django还重的Web框架
- 可以快速生成网站
-
三阶拆分
2. Views
-
路由
- 路由参数获取
- <>
- 语法:
<converter:name>
- converter
- int
- float
- string
- 以
/
作为结尾的
- 以
- path
- 从path修饰开始,后面的东西都是我们的
/
没有作用了
- uuid
- any
- 语法:
-
视图函数
- 默认支持GET、HEAD、OPTIONS
- 其余请求不支持
- 想支持其余请求需要手动注册
-
Flask有四大内置对象
- Request
- request
- Session
- session
- G
- g
- Config
- 在模板中config
- 在python代码中,app.config
- Request
-
小结
3. Request
- args
- 请求参数
- query_string
- query_params
- get请求参数
- 它并不是get专属,所有请求都能获取这个参数
- form
- 表单数据
- post请求参数
- 直接支持put,patch
- ImmutableMultiDict
- args和form都是这个类型
- dict子类
4. Response
- 创建Response的三种方式
- 直接返回字符串
- make_response
- 直接构建Response
- 参数设置
- 内容
- 状态码
- render_template
- 帮助把模板变成html字符串
- 重定向
- redirect
- 反向解析:url_for
- 终止处理
- abort:本质上就是一个exception
- HttpException:
- 子类指定两个属性即可实现
- code
- description
- 异常捕获
- 可以提升程序交互
- 让程序变得友好
- 注册errorhandler
5. 会话技术
-
跨请求共享数据
-
出现原因
- web开发中http都是短连接
- http请求是无状态的
- 请求从request开始,到response就结束了
-
Cookie
- 客户端会话技术
- 数据存储在客户端
- key-value
- flask中的cookie默认对中文等进行了处理,直接可以使用中文
-
Session
- 服务端会话技术
- 数据存储在服务器
- key-value
- flask中
- 将session存储在cookie中
- 对数据进行序列化
- 还进行了base64
- 还进行了zlib压缩
- 还传递了hash
- session的时间是31天
-
Token
-
flask-session
- 实现了服务端session
- 将数据存储在服务端,将数据对应的key存储在cookie中
- RedisSessionInterface
- save_session:将数据进行了pickle序列化
-
flask-bootstrap
- bootstrap/base.html
- html_attribs:给整个html添加属性
- html
- head
- title
- metas
- styles
- body_attribs
- body
- navbar:导航条
- content:内容
- scripts
- body
- head
- bootstrap/base.html
-
小结
6. 模型和模板
-
模板路径默认在Flask(app)创建的路径下
-
如果想自己指定模板路径
- 在Flask创建的时候,指定template_folder
- 在蓝图创建的时候,也可以指定template_folder
- 蓝图指定此蓝图同意前缀:
/xxx
- 模板中使用反向解析和在Python代码中一样
- url_for
-
静态资源
- 静态资源在flask中是默认支持的
- 默认路径在和flask同级别的static中
- 想要自己指定
- 可以Flask创建的时候指定 static_folder
- 也可以在蓝图中指定
- 静态资源也是有路由的
- endpoint是static
- 参数有一个filename
{{ for_for('static', filename='xxx') }}
-
flask-debugtoolbar
- 从Django中借鉴
- 样式基本一致
- 使用方式更简单
- 安装
- 使用app初始化
-
模型
- 约束
- 模型信息指定
- 表名映射
- _tablename_
- 模型继承
- 默认继承并不会报错,它会将多个模型的数据映射到一张表中,导致数据混乱,不能满足基本使用
- 抽象的模型是不会在数据库中产生映射的
- _abstract_ = True
- 表名映射
- 文档
- falsk-sqlalchemy
- sqlalchemy
- 项目中数据库优化
- 怎么连接
- 连接多少个
- django和flask
- 默认都是有数据库连接池的
- 数据查询
- 获取单个对象
- first
- get
- get_or_404
- 获取结果集
- all
- 特殊、特例
- 列表:list
- filter
- BaseQuery对象
- _str_ 输出的是这个对象数据的SQL
- 条件
- 类名.属性名.魔术方法(临界值)
- 类名.属性名 操作符运算符 临界值
- contains
- startswith
- endswith
- in_
- link
- _gt_
- _ge_
- _lt_
- _le_
- 筛选
- filter_by()
- offset()
- limit()
- order_by()
- get()
- first()
- paginate()
- offset和limit不区分顺序,都是先执行offset
- order_by调用必须在offset和limit之前
- 与或非
- _and
- _or
- _not
- BaseQuery对象
- filter_by
- 用在级联数据上
- 条件语法精准
- 字段 = 值
- 级联数据
- 获取
- 手动实现获取
- 使用关系 relationship 进行级联查询
- 反向引用
- 关系
- 1:1
- ForeignKey + Unique
- 1:M
- ForeignKey
- M:N
- 额外关系表
- 两个 ForeignKey
- 1:1
- 获取
- 筛选在flask-sqlalchemy中,all如果使用,只能放在最后
- all
- 获取单个对象
-
小结
7. 数据传输加密反爬
- 爬虫
- 数据获取
- 数据提取
- 数据存储
- 反爬
- 数据加密反爬
- 在服务端对数据进行特定算法的加密
- 在客户端进行数据的解密
- 浏览器还是可破解的
- Android或IOS移动端,破解率基本为零
8. 钩子函数
- 面向切面编程
- 动态介入请求流程
- before_request
- after_request
- Django请求流程
- urls -> views
- views -> models
- models -> views
- views -> response
- 添加中间件
- client -> process_request: list
- 逐一进行process_request
- process_request -> urls
- urls -> process_view: list
- 逐一进行process_view
- process_view -> views
- views -> models
- models -> views
- views -> response
- response -> process_response: list
- 逐一进行process_response
- 四大内置对象
- request
- session
- g
- 跨函数传递数据
- 设置全局变量
- config (app)
- python flask:current_app.config
- 一定是在项目启动之后
9. 用户激活、手机、邮箱
-
用户激活
- 邮箱
- 异步发送邮件
- 在邮件中包含激活地址
- 激活地址接收一个一次性的token
- token是用户注册的时候生成的,存在了cache中
- key-value
- key:token
- value:用户的一个唯一标识
- 短信
- 同步操作
- 邮箱
-
小结
10. Flask-RESTful
-
输出
- 默认输出字典,可以直接进行序列化
- 如果包含对象
- 默认会抛出异常,对象不可JSON序列化
- 使用格式化工具
- marshal 函数
- marshal_with 装饰器
- 条件
- 格式
- 字典格式
- 允许嵌套
- value 是 fields.xxx
- 数据
- 允许任何格式
- 如果格式和数据完全对应,数据就是预期格式
- 如果格式比数据种的字段多,程序以然正常运行,不存在的字段是默认值
- 如果格式比数据中的字段少,程序正常执行,少的字段不会显示
- 以格式的模板为主
- 格式
- 结论
- 想要什么格式的返回
- 格式工具(模板)就是什么样的
- 和传入的数据没什么直接关系
- 格式和数据的映射
- 格式中的字段名和数据中的字段名需要一致
- 也可以手动指定映射
attribute='property_name'
- 也可以对属性指定默认值
- default
- 指定默认值,值传递使用传进来的值
- 未传递,则使用默认值
- 格式中的字段名和数据中的字段名需要一致
- fields
- Raw
- format
- output
- 调用
- 将数据传递进格式化工具的时候,先获取值 output
- 再对值进行格式化 format
- String
- 继承Raw
- 将value进行格式化
- 转换成兼容格式的text
- Integer
- 继承自Raw
- 重写了初始化,将default设置为0
- 重写格式化,直接将value转换成int
- Boolean
- 继承自Raw
- 重写格式化,直接将 value 转换成 bool
- Nested
- 继承自Raw
- 重写output
- 进行marshal
- List
- 继承自Raw
- 重写了output
- 判断你的类型
- 对不同的类型进行不同的处理
- dict 直接进行处理
- list 迭代处理
- 重写format
- 进行格式化
- Raw
-
输入
- RequestParser
- 使用过程
- 先定义一个RequestParser对象
- 向对象中添加字段
- 从对象中获取字段
- 对象在添加参数的时候,可以实现数据的预校验
- 参数是否必须
- 数据的类型
- 还可以设置错误提示
- 接收多个值: action=append
- 也可以接收指定别名
- location可以指定参数的来源
- 可以配合 action=append一起用
- 获取多个来源的同名变量
- 使用过程
- RequestParser
-
爬虫与反爬虫
- 基于IP频率反爬
- 客户端使用代理服务器
- 基于UA的反爬
- 使用UA池
- 基于Cookie或用户反爬
- Cookie池
- 登录大量账号,存储cookie
- 基于IP频率反爬
-
小结
11. 公司组成、项目架构
-
公司
- 找工作的途径
- 投递简历
- 至关重要
- 一定要自己写
- 内推
- 投递简历
- 人力
- 人力资源
- 人员招聘
- 员工考核
- 社保公积金
- 员工关系
- 薪资管理
- 人力资源
- 行政
- 打杂的
- 收发快递
- 接待访客
- 交物业水电
- 拉拉网线
- 设备采购
- 技术
- 产品经理
- PRD
- 项目经理 | 技术经理 | CTO
- UI(UD、UE)
- DBA数据库工程师
- 后端
- 移动端
- 数据分析
- 数据分析师
- 爬虫
- 金融量化交易
- 信息采集
- 爬虫
- 后端
- Web
- 前端
- HTML
- 移动端
- 测试
- 黑盒测试
- 白盒测试
- 运维
- 产品经理
- 财务
- 发工资
- 工资构成
- 全额缴税和五险一金
- 不超过10%(北京)
- 基本工资 + 津贴 + 报销款
- 基本工资 + 绩效 + 现金
- 全额缴税和五险一金
- 工资构成
- 发工资
- 运营推广
- 网络推广
- 百度竞价
- 各大IT论坛贴吧
- 线下推广
- 地铁推广
- 去指定区域推广
- 小区推广
- 口碑运营(公关)
- 网络推广
- 销售
- 渠道
- 线上销售
- 网络销售
- 电话销售
- 线下销售
- 实体店
- 体验店
- 院校
- 班主任
- 售后
- 客服
- 就业老师
- 品保
- 班主任
- 就业老师
- 教务
- 稽查
- 回访电话
- 法务
- 律师团队
- 找工作的途径
-
开发流程
- 产品
- 开会讨论
- 架构
- 框架选型
- 数据库开始
-
加班
- 弹性制工作
- 晚到晚走
- 最近比较忙,需要加班
- 吃饭、交通
- 加班费
- 加班有统计,可以调休
- 996
- 早9晚9上6天
- 弹性制工作
-
公司
- 常规公司
- 通过融资进行发展的公司
- 外包公司
- 驻地开发
- 出差
- 在自己公司开发
- 驻地开发
- 国企
- 常规公司
-
公司发展历程
- 天使投资
- PPT产品
- 固定页面的产品
- A轮
- 扩大规模
- B轮
- 优化产品
- 占领市场
- 对赌
- C轮
- D轮
- E轮
- IPO上市
- 天使投资
-
工资
- 期权
- 股权
12. 淘票票
-
开发
- 淘票票
- 端
- 淘票票后端
- 淘票票公司自己管理
- 客户端
- 看电影用户准备的
- 影院端
- 电影放映
- 淘票票后端
-
通用模块
- 用户体系
- 用户权限
- 用户角色
- 电影
- 淘票票后端
- 增删改查
- 淘票票影院端
- 查询
- 淘票票客户端
- 查询
- 淘票票后端
- 排挡
- 淘票票后端
- 增删改查
- 影院端
- 增删改查
- 客户端
- 查
- 淘票票后端
- 影票
- 淘票票后端
- 增删改查
- 影院端
- 增删改查
- 客户端
- 增删查
- 淘票票后端
- 用户体系
-
可扩展
- 优惠券
- 积分系统
- 影院会员系统
- 评价系统
- 套餐
- 定位(手机、浏览器)
- 地址
- 后端规划好
- 影院端添加
-
多个接口拥有通用功能
- 如何复用代码
- 装饰器
- 钩子函数
- 直接封装一个函数
- 创建一个父类
- 如何复用代码
-
淘票票后端
- 管理淘票票用户
- 淘票票影院管理
- 电影
-
淘票票影院端
- 后端购买来的电影播放权
- 电影
- 放映厅
- 排挡
- 关系表
- 电影和放映厅 + 时间
- 后端购买来的电影播放权
-
淘票票客户端
- 查看电影
- 查看影院
- 查看排挡
- 下单
- 找到具体排挡
- 选座(座位锁定),并发处理
- 订单过期
- 支付
- 查看电影
-
项目架构
- 一个项目入口
- App/_init_
- apis
- admin
- movie_admin
- movie_user
- models
- admin
- movie_admin
- movie_user
- 另外一种架构
- FlaskTpp
- _init_
- settings
- ext
- Admin
- apis
- models
- MovieAdmin
- apis
- models
- MovieUser
- apis
- models
- FlaskTpp
- 一个项目入口
-
系统设计
- 客户端 - 用户系统 - 字段 - username - password - phone - email - is_delete - permission - 权限设计 - 类似于linux权限设计 - 精髓,一个字段可以代表多种权限 - 还能分成两种 - 完全和linux中一样 - 使用二进制 - 所有的初始权限值都是2的n次幂 - 只是给一个数值 - 数值越大,权限越高 - 数值大的包含数值小的所有权限 - 多表设计权限系统 - 用户表 - 权限表 - 用户权限表
-
Linux权限设计
-
FlaskTpp
- 开发流程
- 产品经理提出需求
- 开会,评审
- 要添加的功能,周期(时间)
- 数据设计
- DBA
- 架构师
- 后端经验丰富的工程师
- 自己设计
- 建库建表
- 模型建立
- 对数据进行操作
- CRUD
- 和前端联调
- 前端需要请求接口
- 接口对接
- API文档
- 接口功能
- 接口地址
- 接口所需参数
- 哪些是必须的,哪些是非必须的,哪些是通用参数
- 接口返回数据类型
- 数据字段
- 状态码
- 错误码
- 设计操作的权限
- 登录才能操作
- 权限级别
- 送测
- 测试工程师会有bug反馈
- 修复bug
- 送测
- 上线
- 开发流程
-
端
- 一个项目至少有两端
- 一端用户端
- 后台管理端
- 大部分项目都是有三端的
- 用户端
- Web
- 移动端
- Android
- IOS
- 微信端
- 商家端
- Web
- 移动端
- Android
- IOS
- 微信端
- 后台管理端
- Web
- 移动端
- Android
- IOS
- 微信端
- 用户端
- 我们实现使用RESTful
- 用户端的接口
- 不需要再关注展示端的具体实现
- 商家端的接口
- 后台管理接口
- 用户端的接口
- 一个项目至少有两端
-
Property
- 将函数转换成属性
- 动态干预数据的存取
-
权限
- 两种设计
- 单个字段实现所有权限
- Linux:高格调权限设计
- 使用二级制实现
- 每一种权限使用一个不重复的二进制确定
- 2的n次幂的值
- 优点
- 各种权限互不干扰
- Linux:高格调权限设计
- 包含模式权限
- 值越大权限越多,包含值小的所有权限
- 单个字段实现所有权限
- 多表实现权限
- 用户表
- 权限表
- 用户权限表(用户表和权限表多对多的关系)
- 两种设计
-
装饰器
- 面向切面编程的一部分
- 再不修改原代码的情况下,添加功能、逻辑控制
- 装饰器上内部参数
- *args:用来接收位置参数
- 关键字参数默认值可以自动处理
- 如果传递关键字参数,就需要我们自己处理
- 接收参数
- 传递参数
- **kwargs:用来接收关键字参数
- 如果原函数拥有返回值
- 默认只有调用的话,返回值会被丢弃
- 想接收返回值,要进行数据的返回
- *args:用来接收位置参数
-
权限系统
- Linux
- 权限分类
- 1:读权限
- 2:写权限
- 4:修改权限
-
特殊登陆
- 扫码登录
- 前置条件
- 有一个登录好的账号
- 使用登录好账号中的token来访问自己的登录接口
- 常规登录接口
- 用户名
- 密码
- 手机号
- 邮箱
- 特殊登录接口
- 直接可以通过token进行登录
- 扫码扫出来的就是那个特殊的登录接口
- 常规登录接口
- 前置条件
- 跨应用登录
- 第三方登录
- 扫码登录
-
城市导入脚本
- 获取城市信息
- 将城市信息读出来
- 插入数据库中
-
项目目前状况
- 三端划分
- 客户端
- 商家端
- 后台管理
- 客户端
- 用户模块
- 注册登录
- 信息修改
- 用户删除(不允许)
- 权限
- 用户模块
- 商家端
- XXX
- 后端
- XXX
- 通用
- 地址管理
- 三端划分
-
电影
- 电影属于哪个公司
- 演员
- 操作
- CRUD
- C
- 应该只有后台登录的管理员能创建
- token认证
- 会出现多个端token混乱
- 不同token对应相同的id值
- 解决方案:
- token 添加前缀或后缀
- 修改表结构,user_id的值是字符串,里面存uuid
- C
- CRUD
-
电影公司
-
演员表
-
接下来
- 电影模块
- 电影哪来的(后端)
- 后端
- 用户实现(淘票票管理系统)
- 可以实现电影的增删改查
- 客户端就可以实现电影查询
- 查询电影院(影院端)
- 用户实现(影院端)
- 获取电影列表
- 购买电影播放权
- 电影模块
-
再之后
- 电影院有排挡
- 用户浏览具体排挡下单
- 票房排行
- 统计电影卖的所有的票的总和
- 电影
- 排挡
- 订单
- 价钱
- 订单
- 排挡
- 热度排行
-
影院端
- 用户
- 一个用户对应多个电影院具体地址信息
- 用户购买的电影播放权
- 放映厅
- 排挡
- 用户
-
排挡之后
- 用户可以查看排挡
- 下单(锁单)
- 支付
-
模型图
-
电影院模型图
-
homework
- 集成支付宝支付
- 添加校验
- 作为获取
- 将已售卖的票剔除下去
- 将锁单的票剔除下去
- 锁单的票在过期后应该将座位归还
- 作为获取
-
座位
- 所有座位应该是大厅的座位表
- 剔除已经卖了的
- 已支付
- 已取票
- 锁单
- 已下单,但未支付
-
并发
- 变并行为串行
- 加锁
- 悲观锁
- 对数据操作加锁
- 乐观锁
- 在读取获得的数据
- 操作完成再读一遍,和预期的一样
- 悲观锁
-
支付
- 如何确保付款
- 核心逻辑第三方平台不会暴露给后端服务器的
- 直接和支付平台对接的是客户端
- 客户端可以返回给服务器一个支付状态
- 客户端并不可信
- 还要有一个确保策略
- 接收支付宝的回调
- notify_url
- 已付款待确认就是客户端告诉你成功了,但是还没有收到支付宝的回调
-
项目简单回顾
- 端
- 用户端
- 商家端
- 后台管理端
- 用户模块
- 用户权限
- Linux
- 多表
- 电影
- 商家电影授权
- 商家和电影的关系表
- 电影院地址
- 级联到商家
- 放映厅
- 坐标系
- 级联到电影院地址
- 排挡
- 放映厅和电影
- 电影已经买了的,授权了的
- 订单
- 排挡和用户
- 座位筛选
- 将已经买了的
- 锁定的
- 订单锁定
- 懒处理方式
- 通过一个过期时间搞定
- 订单生成
- 座位表获取
- 座位表确认
- 并发
- 锁
- 乐观锁:操作前和操作后对数据进行比对,如果满足预期则是成功
- 悲观锁:真的给库和表加锁,一定能成功,效率低
- 事务
- 默认ORM开启事务
- begin
- commit
- rollback,回滚,多个操作的时候才有意义
- 锁
- 支付
- 和django中一样
- 支付注意配置支付账号的信息
- 支付的时候调用指定的客户端
- web
- phone
- 区别是调用的接口不一样,参数都是一样的
- 使用的库封装了,对应的就是函数名不一样
- 确保支付结果
- 接收支付宝的回调
- 端
-
票房排行
-
电影和钱 来个排序
-
电影表
- 钱
- 订单
- 电影
- 排挡
- 订单
- 排挡
-
用户权限
-
多表
-
用户表
-
权限表
-
用户权限表
-
权限组表
-
权限组权限表
-
用户权限组表
-
用户组
-
用户组表
-
用户组权限组表
-
用户组权限表
-
-
权限组设计
-
用户权限判断
- 直接判断用户权限
- 获取所在组,组所拥有的权限
-
只要有一个存在,即存在
-
-
多表加入分组聚合查询
-
Django扩容
- 执行原生sql
- objects.raw(“sql”)
- 想做字段选择
- defer:不要哪些字段
- only:只要哪些字段
- 执行原生sql
-
13. nginx
-
nginx
-
测试:
sudo nginx -t -c /mnt/e/1-Work/3-Code/python_projects/8-Flask/Day23/FlaskTpp/config_ubuntu.conf
-
运行:
sudo nginx -c /mnt/e/1-Work/3-Code/python_projects/8-Flask/Day23/FlaskTpp/config_ubuntu.conf
-
查看:
ps -ef|grep nginx
-
文件:
#user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; # 负载均衡 # upstream my_server{ # server 10.0.122.64:8000 weight=1; # server 10.0.122.64:8000 weight=1; # } server { listen 80; server_name 10.16.30.12; #root /mnt/e/1-Work/3-Code/python_projects/6-AXFProject/GPAXF; #charset koi8-r; #access_log logs/host.access.log main; #location /static { # alias /mnt/e/1-Work/3-Code/python_projects/6-AXFProject/GPAXF/static; # root html; # index index.html index.htm; #} location / { # uwsgi include /etc/nginx/uwsgi_params; uwsgi_pass 0.0.0.0:8888; # runserver # proxy_pass http://127.0.0.1:5000; # 负载均衡配置 # proxy_pass http://my_server; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
-
-
uwsgi
-
初始化:
uwsgi --ini uwsgi.ini
-
停止:
uwsgi --stop uwsgi.pid
-
重启:
uwsgi –reload uwsgi.pid
-
文件
[uwsgi] # 使用nginx连接时,使用 socket=0.0.0.0:8888 # 直接作为web服务器使用 # http=0.0.0.0:8888 # 配置工程目录 chdir=/mnt/e/1-Work/3-Code/python_projects/8-Flask/Day23/FlaskTpp # 配置项目的wsgi目录,相对工程路径 wsgi-file=manage.py #router callable=app # 配置进程,线程信息 processes=4 threads=10 enable-threads=True master=True # 进程id存储文件 pidfile=uwsgi.pid daemonize=uwsgi.log
-
14. logging
-
四大组成
- Logger
- 和代码直接对接
- Handler
- 处理者
- 日志处理策略
- Filter
- 过滤器
- Formatter
- 格式化
- Logger
-
日志有级别
-
日志处理流程
- 通过Logger对象进行输出
- 交给Handler处理者进行处理
- 处理者可以对输出样式进行格式化
- 也可以对数据进行过滤
-
Django settings配置样本
# 日志配置 LOGGING = { 'version': 1, #使用的python内置的logging模块,那么python可能会对它进行升级,所以需要写一个版本号,目前就是1版本 'disable_existing_loggers': False, #是否去掉目前项目中其他地方中以及使用的日志功能,但是将来我们可能会引入第三方的模块,里面可能内置了日志功能,所以尽量不要关闭。 'formatters': { #日志记录格式 'verbose': { #levelname等级,asctime记录时间,module表示日志发生的文件名称,lineno行号,message错误信息 'format': '%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s' }, 'simple': { 'format': '%(levelname)s %(module)s %(lineno)d %(message)s' }, 'myself': { 'format': %(levelname)s - %(asctime)s - %(message)s } }, 'filters': { #过滤器:可以对日志进行输出时的过滤用的 'require_debug_true': { #在debug=True下产生的一些日志信息,要不要记录日志,需要的话就在handlers中加上这个过滤器,不需要就不加 '()': 'django.utils.log.RequireDebugTrue', }, 'require_debug_false': { #和上面相反 '()': 'django.utils.log.RequireDebugFalse', }, }, 'handlers': { #日志处理方式,日志实例 'console': { #在控制台输出时的实例 'level': 'DEBUG', #日志等级;debug是最低等级,那么只要比它高等级的信息都会被记录 'filters': ['require_debug_true'], #在debug=True下才会打印在控制台 'class': 'logging.StreamHandler', #使用的python的logging模块中的StreamHandler来进行输出 'formatter': 'simple' }, 'file': { 'level': 'INFO', 'class': 'logging.handlers.RotatingFileHandler', # 日志位置,日志文件名,日志保存目录必须手动创建 'filename': os.path.join(BASE_DIR, logs, debug.log), #注意,你的文件应该有读写权限。 # 日志文件的最大值,这里我们设置300M 'maxBytes': 300 * 1024 * 1024, # 日志文件的数量,设置最大日志数量为10 'backupCount': 10, # 日志格式:详细格式 'formatter': 'verbose', 'encoding': 'utf-8', # 设置默认编码,否则打印出来汉字乱码 }, }, # 日志对象 'loggers': { 'django': { #和django结合起来使用,将django中之前的日志输出内容的时候,按照我们的日志配置进行输出, 'handlers': ['console', 'file'], #将来项目上线,把console去掉 'propagate': True, #冒泡:是否将日志信息记录冒泡给其他的日志处理系统,工作中都是True,不然django这个日志系统捕获到日志信息之后,其他模块中可能也有日志记录功能的模块,就获取不到这个日志信息了 }, 'my': { 'handlers': ['debug'], 'level': 'DEBUG', 'propagate': False } } }
- ☁️ 我的CSDN:https://blog.csdn.net/qq_21579045
- ❄️ 我的博客园:https://www.cnblogs.com/lyjun/
- ☀️ 我的Github:https://github.com/TinyHandsome