flask - 数据交互

flask

安装

pip install flask

项目结构
  • manage.py 用来控制程序
  • App/init 初始化文件
    • 初始化整个Flask对象,以及Flask所用的各种插件
  • App/settings 项目配置文件
    • 配置整个项目运行环境
  • App/ext.py
    • 项目得扩展库
    • 第三方扩展库打包处理
  • App/views
    • 视图函数
    • 处理业务逻辑
    • 协调模板和模型之间的关系
  • App/models
    • 模型
    • 定义模型结构
    • 获得数据库中得表的关系映射

5、Flask数据交互

5.1、使用Flask处理表单

5.1.1、使用Flask处理通用表单
from flask import Flask,render_template,request
app = Flask(__name__)
@app.route('/')
def hello_world():
	return render_template('index.html')  #使用render_template()函数渲染模板

@app.route('/login', method = ['GET','POST'])  #定义路由,指定访问方法
def login():
	if request.method == 'GET':  #判断请求方法
		return "这是get请求"
	else:
		return "这是post请求"
if __name__ == '__main__':
	app.run(debug = True)
5.1.2、使用Flask-WTF处理表单
1、Flask-WTF安装

pip install flask-wtf ;

2、启用CSRF保护

Flask-WTF提供了对所有From表单免受跨站请求伪造(Cross-Site Request Forgery,CSRF)攻击的技术支持。
要想启用CSRF保护,可以在Flask根目录下新增的config.py中定义两个变量:
CSRF_ENABLED = True
SECRET_KEY = ‘x1xx3x3x4x5’
(尽可能复杂)

3、WTF表单登录实例
### config.py
import os
SECRET_KEY = os.urandom(24)    # 生成SECRET_KEY(密钥)
CSRF_ENABLED = True
### form.py
from flask_wtf import Form  # 引入Form基类
from wtforms import StringField,PasswordField  # 引入Form元素父类
from wtforms.validators import DataRequired,Length  # 引用Form验证父类
class BaseLogin(Form):
	# 用户名
	name = StringField('name',validators = [DataRequired(message = "用户名不能为空"), Length(6,16,message = "长度位于6-16之间")], render_kw = {'placehoider' :'请输入用户名'})
	# 密码
	password = PasswordField('password', validators = [DataRequired(message = "密码不能为空"), Length(6,16,message = "长度位于6-16之间")],render_kw = {'placeholder':'请输入密码'})
	
### app.py
from flask import Flask,flash
from flask import url_for,render_template
from forms import BaseLogin
import config
app = Flask(__name__)
app.config.from_object(object)
@app.route('/login',method = ['GET','POST'])
def baselogin():        # 定义视图函数
	form = BaseLogin()  # 进行表单验证
	# 判断验证提交是否通过
	if form.validate_on_submit():
		flash(form.name.data+'|'+form.password.data)  # flash进行消息闪现
		return '表单数据提交成功'     # 返回数据
	else:
		# 渲染
		return render_template('login.html',form = form) # 渲染模板
@app.route('/')
def hello_world():
	return "hello world"
if __name__ == '__main__':
	app.run(debug=True)

5.2、使用Flask上传文件

5.2.1、简单实现

Flask文件上传需要注意以下3点要求:
1、一个< form >标签被标记有 enctype = multipart/form-data , 并且在里面包含一个< input type=file> 标签;
(例如:< form action="" method=“post” enctype=“multipart/form-data”> )
2、服务端应用通过请求对象上的files字典访问文件;
3、使用文件的save()方法将文件永久地保存在文件系统上的某处。

### app.py
from flask import Flask,render_template,request
import os
from os import path
# 导入secure_filename模块,将文件名中所有的中文名过滤掉,只剩下文件后缀名
from werkzeug.utils import secure_filename

app = Flask(__name__)
@app.route('/',method = ['GET','POST'])
def hello_world():
	if request.method == 'GET':
		return render_template('upload.html')
	else:
		f = request.file['file']  # 获取文件流
		filename = secure_filename(f.filename)  # 去掉中文命名
		f.save(path.join('static/uploads',filename))  # 使用.save()方法保存文件
		return "文件上传成功"  ##返回数据
if __name__ == '__main__':
	app.run(debug=True)
5.2.2、改进上传功能

存在的问题:
1、文件没有进行重命名,多个用户可能会存在上传同名文件的问题;
2、没有实现文件目录的自动创建,如果网站部署时忘记创建文件保存目录,则会出现文件保存失败问题,影响用户体验;
3、文件上传时,没有进行必要的文件格式检验,用户可以直接将可执行文件上传到服务器上,影响到服务器的数据安全性。

### app.py
from flask import Flask,render_template,request,send_from_directory
import time
import os
from os import path
from werkzeug.utils import secure_filename
import platform
app = Flask(__name__)
# 根据系统操作系统调整路径格式
if platform.system() == "Windows":
	slash = '\\'
elif platform.system() == "Linux":
	slash = '/'
UPLOAD_PATH = os.path.curdir + slash + 'uploads' + slash
@app.route('/',method = ['GET','POST'])
def hello_world():
	if request.method == 'GET':
		return render_template('upload.html')
	else:
		if not os.path.exists(UPLOAD_PATH):  # 判断文件保存路径是否存在
		 	os.makedirs(UPLOAD_PATH)  # 没有目录则创建目录
		# 表单验证
		form = UploadForm(CombinedMultiDict([request.form,request.files])) 
		if form.validate():
			f = reuqest.files['file']  # 获取文件流
			filename = secure_filename(f.filename)  # 获取文件名称
			ext = filename.rsplit('.',1)[1]  # 获取文件后缀
			unix_time = int(time.time())  # 获取时间
			new_filename = str(unix_time)  + '.' + ext  # 对文件重命名
			file_url = UPLOAD_PATH + new_filename
			f.save(path.join(UPLOAD_PATH, new_filename))  # 保存文件
			return "上传文件成功"
		else:
			return "只支持jpg、png以及gif格式的文件"
# 访问上传文件   https//127.0.0.1:5000/images/xxx.jpg/
@app.route('/images/<filename>/',method=['GET','POST'])
def get_image(filename):  # 视图函数,访问图片
	# 得到绝对路径
	dirpath = os.path.join(app.root_path,'uploads')
	# return send_from_directory(dirpath,filename,as_attachment=True) #下载方式
	return send_from_directory(dirpath,filename)  # 在线浏览方式
if __name__ == '__main__':
	app.run(debug=True)

### form.py
from wtforms import Form,FileField,StringField
from wtforms.validators import InputRequired
from flask_wtf.file import FileRequired,FileAllowed
class UploadForm(Form):
	# FileRequied验证是否为空;FileAllowed:指定文件支持的格式
	file = FileField(validators=[FileRequired(), FileAllowed(['jpg','png','git']) )
	

5.3、Cookie的使用

5.3.1、Cookie的基本概念

Cookie是一种能够让网站服务器把少量数据存储到客户端的硬盘或者内存,或者是从客户端的硬盘读取数据的一种技术。当用户访问服务器并登录成功后,服务器向客户端返回一些数据(Cookie),客户端将服务器返回的Cookie数据保存在本地,当用户再次访问服务器时,浏览器自动携带Cookie数据给服务器,服务器就知道访问者的身份信息。
Cookie的基本语法:
set_cookie(name,value,expire,path,domain,secure)
name : 必需项,规定Cookie的名称
value:必需项,规定Cookie的值
expire: 可选项,规定Cookie的有效期
path: 可选项,规定Cookie在当前web下哪些目录有效
domain:可选项,规定Cookie作用的有效域名
secure:可选项,规定是否通过安全的HTTPS链接来传输Cookie

5.3.2、Cookie的基本使用

1、设置Cookie
设置Cookie有两种方法,一种时通过Response对象来设置,另一种时通过直接设置表单头来实现。

### 通过Response对象来设置Cookie
from flask import Flask,request,Response
app = Flask(__name__)
@app.route('/')
def set_cookie():
	# 创建响应对象
	resp = Response("进行Cookie设置!")
	# 设置cookie名为username,cookie名称为bing,默认关闭浏览器失效
	resp.set_cookie("username","bing")   # 存入cookie
	return resp
if __name__ == '__main__':
	app.run(debug=True)
### 通过设置表单头来设置Cookie
from flask import Flask,request,Response
app = Flask(__name__)
@app.route('/')
def set_cookie():
	# 创建响应对象
	resp = Response("进行Cookie设置!")
	# 设置cookie名为username,cookie名称为bing,默认关闭浏览器失效
	resp.headers["Set_Cookie"] = "username=bing; Expires=SUN,01-Dec-2020 20:20:02 GMT; Max-Age=3600; path=/")   
	return resp
if __name__ == '__main__':
	app.run(debug=True)

2、查看cookie

@app.route('/get_cookie')
def get_cookie():
	username = request.cookies.get('username')
	return username

3、删除cookie

@app.route('/del_cookie')
def del_cookie():
	resp = Response("删除cookie")
	resp.delete_cookie("username")
	return resp

4、cookie基本操作综合实例

from flask import Flask,request,Response
app = Flask(__name__)
@app.route('/')
def set_cookie():   # 设置cookie
	# 创建响应对象
	resp = Response("进行Cookie设置!")
	# 设置cookie名为username,cookie名称为bing,保持1个小时失效,默认关闭浏览器失效
	resp.set_cookie("username","bing", max_age = 3600)   # 存入cookie
	return resp
@app.route('/get_cookie')
def get_cookie():   # 获取cookie
	username = request.cookies.get('username')
	return username or "没有获取到username"
@app.route('/del_cookie')
def del_cookie():  # 删除cookie
	resp = Response("删除cookie")
	resp.delete_cookie("username")
	return resp
if __name__ == '__main__':
	app.run(debug=True)
5.3.3、设置cookie的作用域

5.4、Session的使用

5.4.1、session的基本使用

1、设置Session
通过session[‘name’]='value’的方法来设置的,name代表变量名称,value代表变量值。

### 设置session
from flask import Flask,session
import os
app.config['SECRET_KEY'] = os.urandom(24)  # 生成密钥
@app.route('/')
def set_session():
	session['username'] = 'bing'  
	return "设置session成功!"
if __name__ == '__main__':
	app.run(debug=True)

2、获取session值
获取session有两种方法,推荐第二种
(1)result = session[‘username’] : 如果内容不存在,会出现异常
(2)result = session.get(‘username’) : 如果内容不存在,返回None

@app.route('/get_session')
def get_session():
	username = session.get('username')
	return username or 'session 为空'

3、删除session值或者清楚session所有的值
删除单个session值可以用Session.pop(‘key’), 清除多个session的值用Session.clear方法。

@app.route('/del_session')
def del_session():
	session.pop('username')
	# session.clear             # 清空session
	return "Session 被删除"

4、设置Session的过期时间
如果没有指定session的过期时间,默认浏览器关闭后自动结束。
通过 session.permanent = True 可以将过期时间延长至一个月。
还可以设置具体的天数,代码见下:

from datetime import timedelta
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(day=7) # 配置7天有效
@app.route('/')
def set_session():
	session['username'] = 'bing'
	session.permanent = True
	return "session设置成功"

5.5、钩子函数的使用

有时候需要在代码执行的前、中、后时期,强行执行一段我们想要执行的功能代码,实现这种功能的函数,就称为钩子函数。
1、before_first_request() 函数
在第一次请求之前可以执行的函数,只会执行一次。

2、before_request() 函数
每一次请求之前可以执行某个特定功能的函数。一般可以用来检测用户的请求是否合法、权限检查等场景。

3、after_request() 函数
每一次请求之后可以执行的某个特定功能的函数。一般可以用来产生csrf_token验证码等场景。该函数必需给出响应对象(response)。

4、teardown_request() 函数
每一次请求之后都会调用,会接受一个参数,参数时服务器出现错误的信息。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YeYingSec

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值