Day1
Flask框架简介和快速使用
# 谈谈对PythonWeb框架
django —— 大而全 重武器。内部提供ORM Admin Form Session 缓存 信号 CSRF。
flask —— 短小精悍 可扩展强。第三方组件丰富。
tonado —— 短小精悍+异步非阻塞。
其他-微小框架 :web.py bottole.py
# WSGI
django —— wsgi
flask —— werkzeug
# flask 查看app.run内部调用werkzeug
用户管理系统示例
# vscode 英文输入状态,输入! tab键盘即可快速生成html文本
# jinja2 框架
# 登录页面中使用session
# 报错
RuntimeError: The session is unavailable because no secret key was set. Set the secret_key on the application to something unique and secret.
# 解决方案,要在app中加入secret_key
app.secret_key = 'u2jksrls123lisr'
# web调试中找到记录的session
# flask项目保存自动
app.debug = True
# 详细页面传递uid
web页面查看
# 具体代码实现
# app.py
from distutils.log import info
from flask import Flask ,render_template, request,redirect,session
app = Flask(__name__)
app.secret_key = 'u2jksrls123lisr'
app.debug = True
USER_DICT={
'1':{'name':'taohy','age':18},
'2':{'name':'admin','age':30},
'3':{'name':'dabao','age':8}
}
# 登录login页面
@app.route('/login',methods=['GET','POST'])
def login():
if request.method == 'GET':
return render_template('login.html')
# request.args # 获取url中 GET传来的值
# request.form # 获取html中 POST传过来的值
user = request.form.get('user')
pwd = request.form.get('pwd')
if user == 'admin' and pwd =='11111':
# 用户信息放入session
session['user_info']= user
# session['pwd_info'] = pwd
return redirect('/index')
else:
return render_template('login.html',msg = '用户名或密码错误!')
# 后台管理index页面
@app.route('/index')
def index():
user_info = session.get('user_info')
if not user_info:
return redirect('/login')
else:
# return '欢迎'+user_info+'登录后台管理系统'
return render_template('index.html',user_dict = USER_DICT) # 将user_dict传递到html
# 退出系统 删除session
@app.route('/logout')
def logout():
del session['user_info']
return redirect('/login')
# 详细信息页面
@app.route('/detail')
def detail():
user_info = session.get('user_info')
if not user_info:
return redirect('/login')
else:
# 详细页面
# 获取url值
uid = request.args.get('uid')
info = USER_DICT.get(uid)
return render_template('detail.html',info = info) # 将info列表传递给html
if __name__ == '__main__':
app.run()
<!--templates/login.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用户登录</title>
</head>
<body>
<h1>登录</h1>
<form method="post" >
<input type="text" name="user" >
<input type="password" name ="pwd">
<input type="submit" value="提交" >{{msg}}
</form>
</body>
</html>
<!--templates/index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>index页面</title>
</head>
<body>
<ul>
<!-- 将python传递过来的user_dict解析 -->
{% for k,v in user_dict.items() %}
<!-- url传值 -->
<li>用户:{{v['name']}} <a href="/detail?uid={{k}}">查看详情</a></li>
{% endfor %}
</ul>
</body>
</html>
<!--templates/detail.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>详细信息</title>
</head>
<body>
<h1>详细信息</h1>
<!-- 将python后台info列表传递到前台解析出来 -->
<div>{{info.name}}</div>
<div>{{info.age}}</div>
</html>
今日作业
# Flask装饰器 实现(位置、url起别名(不能重复))
# 类似django中间件的东西:before_request装饰器
# 预习 上下文
from threading import local
functools.wraps
functools.partial
面向对象封装
面向对象中 __setattr__ __getattr__ __delattr__
Day2
# 装饰器
# 带参数的装饰器
# 面向对象
封装:
1. 将同一类方法分为一类:方法封装到类中。
2. 将方法中共同的参数封装到对象中:把共用值封装到对象中。
情况a b:
Flask配置文件
Flask框架之创建路由的两种方式
# 一般都用方式一
Flask框架之反向生成URL
Flask框架之自定义路由转换器
Flask框架之app.route参数
Flask框架之获取子域名的路由
Flask框架之视图中添加装饰器
Flask框架之CBV和FBV
常用FBV
Flask框架之请求和响应相关
# 请求相关 request
# 响应相关
Flask框架之模板引擎
# jinja2框架使用
# app.py
from distutils.log import info
from multiprocessing import context
from flask import Flask ,render_template, request,redirect,session,Markup
app = Flask(__name__)
app.secret_key = 'u2jksrls123lisr'
app.debug = True
USER_DICT={
'1':{'name':'taohy','age':18},
'2':{'name':'admin','age':30},
'3':{'name':'dabao','age':8}
}
# 登录login页面
@app.route('/login',methods=['GET','POST'])
def login():
if request.method == 'GET':
return render_template('login.html')
# request.args # 获取url中 GET传来的值
# request.form # 获取html中 POST传过来的值
user = request.form.get('user')
pwd = request.form.get('pwd')
if user == 'admin' and pwd =='11111':
# 用户信息放入session
session['user_info']= user
# session['pwd_info'] = pwd
return redirect('/index')
else:
return render_template('login.html',msg = '用户名或密码错误!')
# 模板全局函数
@app.template_global()
def g_add(a1,a2):
return a1+a2
# 自定义函数
def create_input_one(value):
# 方法一 html加safe安全显示input
return "<input value='%s' />" %value
def create_input_two(value):
# 方法二 py引入markupsafe
return Markup("<input value='%s' />" %value)
# 后台管理index页面
@app.route('/index')
def index():
user_info = session.get('user_info')
if not user_info:
return redirect('/login')
else:
# return '欢迎'+user_info+'登录后台管理系统'
stra = "我是一个字符串"
lista = [1,2,3,4]
# **字典多个值
context={
'k1':'我是context的k1',
'k2':['k2_1','k2_2','k3_2'],
'k3':{'k3_name':'k3','k3_age':20},
'k4':lambda x:x+1, # 传递函数
'k5':create_input_one,
'k6':create_input_two, # 模板内自定义函数
'k7':g_add # 全局模板自定义函数
}
return render_template('index.html',stra=stra,user_dict = USER_DICT,lista=lista,**context) # 将user_dict传递到html
# 退出系统 删除session
@app.route('/logout')
def logout():
del session['user_info']
return redirect('/login')
# 详细信息页面
@app.route('/detail')
def detail():
user_info = session.get('user_info')
if not user_info:
return redirect('/login')
else:
# 详细页面
# 获取url值
uid = request.args.get('uid')
info = USER_DICT.get(uid)
return render_template('detail.html',info = info) # 将info列表传递给html
if __name__ == '__main__':
app.run()
# index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>index页面</title>
</head>
<body>
<p>jinja2框架</p>
<p>传递字符串:</p>
<div>{{stra}}</div>
<p>传递字典——遍历字典:</p>
<ul>
<!-- 将python传递过来的user_dict解析 -->
{% for k,v in user_dict.items() %}
<!-- url传值 -->
<li>用户:{{v['name']}} <a href="/detail?uid={{k}}">查看详情</a></li>
{% endfor %}
</ul>
<p>传递列表——遍历列表:</p>
{% for listaa in lista %}
<div>{{listaa}}</div>
{% endfor %}
<p>传递字典——**多个值:</p>
<div>{{k1}}</div>
<div>{{k2[0]}} {{k2[1]}} {{k2[3]}}</div>
<!--k3.get('dontkonw','dontkonw') 不存在key:dontkonw 默认值给dontkonw-->
<div>{{k3['k3_name']}} {{k3['k3_age']}} {{k3.get('dontkonw','dontkonw')}} </div>
<!--k4函数 给参数执行-->
<div>{{k4(20)}}</div>
<!--方法一 k5自定义函数 新增input html新增安全显示safe-->
<div>{{k5(20) |safe}} </div>
<!--方法二 k6自定义函数 新增input py引入Markup-->
<div>{{k6(20)}} </div>
<p>全局模板函数</p>
<div>{{k7(1,2)}}</div>
</body>
</html>
# layout 使用
session使用和源码流程
after_request
# login 除了登录页面,其他页面执行之前,都要去判断是否登录
Flask框架之特殊装饰器
# 第一次访问
# 定制404页面
# 模板里用到的
Flask框架之闪现
# 经常用的数据存session,不经常用的存flash
Flask中间件
Flask框架之蓝图
# 常用目录框架
# 目录结构划分
# 某一类url加上前缀
# 某一类url加上before_request或者after_request
# 大型项目蓝图,笔记资料里面,自行下载查看!
扩展知识
pipreqs 项目依赖
# 按照依赖
pip3 install pipreqs
# 生成依赖文件 requirements.txt
pipreqs ./
# 安装依赖文件
pip3 install -r requirements.txt
函数和方法
类里面可以是方法,也可以是函数
Day3
课前复习
threading.local学习
# threading.local
作用:为每个线程开辟一块空间进行数据存储。
# 问题:自己通过字典创建一个类似于threading.local的东西。
函数实现:
类实现:
自定义Local思路
自定义Local对象(基于函数)
自定义Local对象(基于面向对象)
Flask上下文管理之本质分析
Flask上下文管理之请求到来处理
第一阶段
Flask上下问管理之视图调用阶段
Flask中的g到底是什么?生命周期?
# 请求中的全局变量
# 单次执行完就销毁了
补充:面向对象的私有字段
Day4
组件的使用和原理
# session存储方式
# 原生的session的bug解决方法
基于pymysql实现用户登录
基于数据库连接池实现用户登录
# pip install DBUtils
数据库连接池总结
wtforms介绍以及用户登录示例
# pip install wtfroms
# python 做表单验证