flask库笔记
关于设置request
方法为form
还是files
基本区别
例如,下列关于文件上传的前端和python后端代码为:
前端代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html>
<head>
<title>Upload File</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
<label for="file">File:</label>
<input type="file" id="file" name="file">
<br>
<input type="submit" value="Upload">
</form>
</body>
</html>后端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16from flask import Flask, request, redirect, url_for
app = Flask(__name__)
app.secret_key = 'your_secret_key'
def upload():
file = request.files.get('file')
if file:
filename = file.filename
file.save(f'uploads/{filename}')
return f'File uploaded successfully: {filename}'
return 'No file uploaded'
if __name__ == '__main__':
app.run(debug=True)这里可见在
upload()
函数中,request
请求后写为:files.get
方法,为什么会写作files.get
而不是form.get
?
关键点在编码方式:enctype=multipart/form-data
该种编码方式将文件以二进制方式进行解析,适合传输如视频音频格式的文件,由于该种文件在请求体中的呈现方式类似于如下形式:1
2
3
4
5
6
7
8--boundary_123456
Content-Disposition: form-data; name="file"; filename="photo.jpg"
Content-Type: image/jpeg
[二进制文件流...]
--boundary_123456--
xxxx
--boundary_123456--而并非为
enctype=application/x-www-form-urlencoded
,即请求体为类似于:k1=a&k2=b
形式,
所以需要使用files.get
形式而非form.gets
底层原理:
Flask的解析逻辑:
Flask 根据 enctype 的类型自动解析请求体:
对普通文本表单(application/x-www-form-urlencoded):
数据被解析到 request.form(一个字典结构,只存文本键值对)。
对文件上传表单(multipart/form-data):
Flask 将 文本字段 的数据放在 request.form,
文件数据则被转移到 request.files(存的是文件对象)。
特殊情况
Q:如果表单既有文件又有文本怎么办?
A:比如上传文件且填写描述:
1 | <form action="/upload" method="POST" enctype="multipart/form-data"> |
外部浏览器打开
后端代码
1 |
|
关于Flask库中ORM设计思想
通俗来说,就是用简单的python代码来代替容易拼错的sql语句:
使用普通的sqlite3库:1
data = cursor.execute("SELECT * FROM user WHERE username='alice';")
使用 Flask-SQLAlchemy库:
1
id = db.Column(db.Integer,primary_key = True)
这里即使用易懂的python语言而非sql语言创建了一个键
username
,并将其定义为主键,数据类型为整数。
完整代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import flask
from flask_sqlalchemy import SQLAlchemy
app = flask.Flask(__name__)
app.config['SECRET_KEY'] = 'thisismysecretkey'
app.config['SQLALCHEMY_DATABASE_URI'] ='sqlite:///test.db'#创建了一个数据库文件
db = SQLAlchemy(app)
class User(db.Model):#定义了一个表的结构
id = db.Column(db.Integer, primary_key=True)#创建了一个整数键,名字为"id"
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
def __repr__(self):
return f'<User {self.username}>'加入新数据:
1
2
3new_user = User(username="Alice",email="123456@qq.com")
db.session.add(new_user)
db.session.commit多说几句,这里为什么要使用
session
?
首先可以自行前往wiki上了解”事务”这个计算机数据库概念,在数据库被操作时,数据库的记录对象会被锁定,只能添加读取或者删除,只有事务结束之后才可以进行下一步操作,防止出现数据丢失的情况。取出数据:
1
2user = User.query.filter_by(username='Alice').first() # 定位数据
print(user) # 输出: <User Alice>….(其他对应操作可以去看菜鸟教程)