开发 python开发-flask

开发-flask-B-python大本营

错误

此系统上禁止运行脚本

1
2
3
4
# 临时修改执行策略(推荐)
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
# 长期解决方案
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

.venv

1
2
3
4
5
6
7
8
9
10
11
12
# 步骤 1:创建虚拟环境
python -m venv venv

# 步骤 2:激活虚拟环境
# macOS / Linux
source venv/bin/activate
# Windows
venv\Scripts\activate

# 步骤 3:安装依赖并生成 requirements.txt
pip install -r requirements.txt # 安装依赖
pip freeze > requirements.txt # 冻结依赖版本

flask

https://www.bilibili.com/video/BV1pT4y1W7C4/?spm_id_from=333.337.search-card.all.click&vd_source=379b5659b7b00bb6caa4cadf9cc37ad6

1
2
3
4
5
6
7
8
9
10
from flask import Flask

app = Flask(__name__)
@app.route("/")
def index():
return "hello flask"

if __name__ == "__main__":
app.run(debug=True)

传入变量

1
2
3
限定变量类型

不限定变量类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from flask import Flask, render_template,url_for,redirect,request,abort,make_response,session,flash
from werkzeug.wrappers.response import ResponseStream


app = Flask(__name__)



@app.route('/hello/<name>')
def hello_name(name):
return f"hello {name}"

@app.route('/int/<int:var>')
def int(var):
return "int {}".format(var)

@app.route('/float/<float:var>')
def float(var):
return "float %.2f" % var

@app.route('/python')
def python():
return "hello python"

@app.route('/flask/')
def flask():
return "hello flask"

if __name__ == "__main__":
app.run(debug=True,host='127.0.0.1',port=5000,threaded=True)

~

是否路径末尾有/

1
路径末尾有/时,实际浏览器访问时有或者没有都可以

app.run

1
2
3
debug

threaded=True 网页速度可能加快
1
2
3
4
5
6
7
8
1. debug=True
启用调试模式:当应用发生错误时,会在浏览器中显示详细的错误信息
自动重载:修改代码后,Flask会自动重启服务器,无需手动重启
注意:生产环境中必须设置为 False,否则会暴露代码细节和安全信息
2. threaded=True
启用多线程处理:Flask会为每个请求创建单独的线程
并发处理:允许同时处理多个请求,而不是一次只处理一个
默认情况下,Flask的调试服务器已经是线程化的,但显式设置可以确保这一点

flask静态文件

render_template

1
2
3
无参数

有参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from flask import Flask, render_template,url_for,redirect,request,abort,make_response,session,flash
from werkzeug.wrappers.response import ResponseStream


app = Flask(__name__)



@app.route('/')
def index():
return render_template("index21.html")

@app.route('/index22/')
def index22():
my_int = 1
my_dict = {"name":"ty"}
my_list = [5,4]
return render_template("index22.html",my_int=my_int,my_dict=my_dict,my_list=my_list)


if __name__ == "__main__":
app.run(debug=True,host='127.0.0.1',port=5000,threaded=True)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的第一个网页</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header>
<h1>欢迎来到我的网站</h1>
</header>
<hr>
<h2>int数据</h2>
</hr>
<br>{{my_int}}</br>
<hr>
<h2>dict数据</h2>
</hr>
<br>{{my_dict["name"]}}</br>
<hr>
<h2>list数据</h2>
</hr>
<br>{{my_list[0]}}</br>
<footer>
<p>版权所有 © 2025</p>
</footer>
<script src="script.js"></script>
</body>
</html>

redirect和url_for

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from flask import Flask, render_template,url_for,redirect,request,abort,make_response,session,flash
from werkzeug.wrappers.response import ResponseStream


app = Flask(__name__)




@app.route('/admin/')
def admin():
return "hello admin"

@app.route('/guest/<guest>/')
def hello_guest(guest):
return "hello %s as guest" % guest

@app.route('/user/<name>/')
def user(name):
if name == "admin":
return redirect(url_for("admin"))
else:
return redirect(url_for("hello_guest",guest = name))


if __name__ == "__main__":
app.run(debug=True,host='127.0.0.1',port=5000,threaded=True)

extends、block

index23.html:

1
2
3
4
5
6
7
8
9
{% extends 'base.html' %}

{% block head %}

{% endblock %}

{% block body %}
<h1>Template</h1>
{% endblock %}

base.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的第一个网页</title>
<link rel="stylesheet" href="{{url_for('static', filename='css/main.css')}}">
{% block head %}{% endblock %}
</head>
<body>
{% block body %}{% endblock %}

</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
{% extends 'base.html' %}
表示这个模板继承自 base.html(基础模板)
类似于面向对象中的继承

{% block head %}... {% endblock %}
定义一个名为 head的区块
通常用于放置页面的头部信息(CSS、JS、title 等)
会替换或填充到 base.html中同名的 block

{% block body %}... {% endblock %}
定义一个名为 body的区块
通常用于放置页面的主体内容
会替换或填充到 base.html中同名的 block

将表单数据发送到模版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from flask import Flask, render_template,url_for,redirect,request,abort,make_response,session
from werkzeug.wrappers.response import ResponseStream


app = Flask(__name__)

@app.route('/student/')
def student():
return render_template("index5.html")

@app.route('/result/',methods=['POST','GET'])
def result():
if request.method == "POST":
rst = request.form
return render_template('result5.html',result=rst)

if __name__ == "__main__":
app.run(debug=True,host='127.0.0.1',port=5000,threaded=True)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的第一个网页</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<table border=1>
{% for key, value in result.items() %}
<tr>
<th>{{ key }}</th>
<th>{{ value }}</th>
</tr>
{% endfor %}
</table>
</body>
</html>

request、ResponseStream

错误abort

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from flask import Flask, render_template,url_for,redirect,request,abort,make_response,session
from werkzeug.wrappers.response import ResponseStream


app = Flask(__name__)

@app.route('/index7/')
def index7():
return render_template("index7.html")

@app.route('/success/')
def success():
return 'logged in successfully'

@app.route('/login/',methods=['POST','GET'])
def login():
if request.method == "POST":
if request.form['username'] == 'admin':
return redirect(url_for('success'))
else:
abort(401)
elif request.method == "GET":
return redirect(url_for("index7"))


if __name__ == "__main__":
app.run(debug=True,host='127.0.0.1',port=5000,threaded=True)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的第一个网页</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<form action="/login" method="POST">
<p>username <input type = "text" name = "username" /></p>
<p><input type = "submit" value = "登录" /></p>
</form>
</body>
</html>

cookie和会话session

1
存在客户端
make_response
1
2
3
resp.set_cookie()
resp.get_cookie()
resp.delete_cookie()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from flask import Flask, render_template,url_for,redirect,request,abort,make_response,session
from werkzeug.wrappers.response import ResponseStream


app = Flask(__name__)



@app.route('/set_cookies/')
def set_cookies():
resp = make_response("success")
resp.set_cookie("aaa_key","aaa_value",max_age=3600)
return resp

@app.route('/del_cookies/')
def del_cookies():
resp = make_response("del_success")
resp.delete_cookie("aaa_key")
return resp

@app.route('/get_cookies/')
def get_cookies():
cookie_1 = request.cookies.get("aaa_key")
return cookie_1

if __name__ == "__main__":
app.run(debug=True,host='127.0.0.1',port=5000,threaded=True)

session

1
存在服务器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from flask import Flask, render_template,url_for,redirect,request,abort,make_response,session
from werkzeug.wrappers.response import ResponseStream


app = Flask(__name__)
app.secret_key = '123456'

@app.route('/')
def index():
if 'username' in session:
user = session['username']
return '登录用户名是:' + user + '<br>' + "<b><a href = '/logout'>点击这里注销</a></b>"
return "您暂未登录,<br><a href='/login'><b>点击这里登录</b></a>"

@app.route('/logout/')
def logout():
session.pop('username',None)
return redirect(url_for('index'))

@app.route('/login/',methods=['POST','GET'])
def login():
if request.method == "POST":
session['username'] = request.form['username']
return redirect(url_for('index'))

elif request.method == "GET":
return render_template("index7.html")

@app.route('/index7/')
def index7():
return render_template("index7.html")

if __name__ == "__main__":
app.run(debug=True,host='127.0.0.1',port=5000,threaded=True)

消息闪现flash

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from flask import Flask, render_template,url_for,redirect,request,abort,make_response,session,flash
from werkzeug.wrappers.response import ResponseStream


app = Flask(__name__)
app.secret_key = '123456'

@app.route("/")
def index():
return render_template("index9.html")

@app.route("/login",methods=['GET','POST'])
def login():
errormsg = None
if request.method == 'POST':
if request.form['username'] != 'admin' or request.form['password'] != 'admin':
errormsg = 'Invalid username or password. Please try agin!'
else:
flash("You were successfully logged in")
return redirect(url_for("index"))
return render_template('login9.html', error=errormsg)


if __name__ == "__main__":
app.run(debug=True,host='127.0.0.1',port=5000,threaded=True)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的第一个网页</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<form method = 'post' action = "/login">
<table>
<tr>
<td>Username</td>
<td><input type='username' name='username'></td>
</tr>
<tr>
<td>Password</td>
<td><input type='password' name='password'></td>
</tr>
<tr>
<td><input type='submit' value='Submit'></td>
</tr>
</table>
</form>
{% if error %}
<p><strong>Error</strong>: {{ error }}</p>
{% endif %}
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的第一个网页</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
<p>{{ message }}</p>
{% endfor %}
{% endif %}
{% endwith %}
<h3>Welcome!</h3>
<a href="{{ url_for('login')}}">login</a>
</body>
</html>

文件上传

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from flask import Flask, render_template,url_for,redirect,request,abort,make_response,session,flash
from werkzeug.wrappers.response import ResponseStream
from werkzeug.utils import secure_filename
import os

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = f'{os.path.dirname(os.path.abspath(__file__))}\\uploaddir\\'
@app.route("/")
def upload_file():
return render_template("upload.html")

@app.route("/uploader",methods=['GET','POST'])
def uploader():
if request.method == 'POST':
f = request.files['file111']
f.save(os.path.join(app.config['UPLOAD_FOLDER'],secure_filename(f.filename)))
return 'file uploaded successfully'
elif request.method == 'GET':
return render_template('upload.html')

if __name__ == "__main__":
app.run(debug=True,host='127.0.0.1',port=5000,threaded=True)
# print(os.path.dirname(__file__))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的第一个网页</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<form action="/uploader" method="POST" enctype="multipart/form-data">
<input type="file" name="file111" />
<input type="submit" value="提交" />
</form>
</body>
</html>

wtform表单处理

wtform案例

CRSF攻击

1
支持避免CRSF攻击
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
from flask import Flask, render_template,url_for,redirect,request,abort,make_response,session,flash
from werkzeug.wrappers.response import ResponseStream
from werkzeug.utils import secure_filename
import os

from flask_wtf import FlaskForm
from wtforms import StringField,IntegerField,TextAreaField,SubmitField,RadioField,SelectField
from wtforms import validators

class ContactForm(FlaskForm):
name = StringField("Name Of Student",[validators.InputRequired("Please enter your name.")])
Gender = RadioField('Gender', choices = [('M','Male'),('F','Female')])
Address = TextAreaField('Address')

email = StringField("Email",[validators.InputRequired("Please enter your email address."),validators.Email("Please enter your email address.")])
Age = IntegerField("age")
language = SelectField('language',choices=[('cpp','C++'),('py','Python')])

submit = SubmitField("Send")

app = Flask(__name__)
app.secret_key = "123456"

@app.route("/",methods = ['GET','POST'])
def contact():
form1 = ContactForm()

if request.method == "POST":
if form1.validate() == False:
flash('All fields are required.')
return render_template('contact11.html',form=form1)
else:
return render_template('success11.html')
elif request.method == 'GET':
return render_template('contact11.html',form=form1)

if __name__ == "__main__":
app.run(debug=True,host='127.0.0.1',port=5000,threaded=True)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的第一个网页</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h2 style="text-align: center;">Contact Form</h2>

{% for message in form.name.errors %}
<div>{{ message }}</div>
{% endfor %}

{% for message in form.email.errors %}
<div>{{ message }}</div>
{% endfor %}

<form action="/" method="post">
<fieldset>
<legend>
Contact Form
</legend>
{{ form.hidden_tag() }}

<div style="font-size: 20px;font-weight: bold;margin-left: 150px;"
{{ form.name.label }}<br>
{{ form.name }}
<br>

{{ form.Gender.label }} {{ form.Gender }}
{{ form.Address.label }}<br>
{{ form.Address }}
<br>

{{ form.email.label }}<br>
{{ form.email }}
<br>

{{ form.Age.label }}<br>
{{ form.Age }}
<br>

{{ form.language.label }}<br>
{{ form.language }}
<br>
{{ form.submit }}
</div>

</fieldset>
</form>
<h3>Welcome!</h3>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的第一个网页</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
Form post successfully
</body>
</html>

SQLAlchemy

1
2
3
4
5
这里并没有安装sqlite能够直接使用是因为SQLAlchemy它底层使用的就是 Python 自带的 sqlite3

sqlite也可以单独安装,然后程序里去连接安装的服务

对象关系映射ORM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
from datetime import datetime

from flask import Flask, render_template,url_for,redirect,request,abort,make_response,session,flash
from werkzeug.wrappers.response import ResponseStream

from flask_wtf import FlaskForm
from wtforms import HiddenField, StringField,IntegerField,TextAreaField,SubmitField,RadioField,SelectField
from wtforms import validators

from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///contacts.db'
app.config["SECRET_KEY"] = "123456"

db = SQLAlchemy(app)

class ContactDAO(db.Model):
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(50))
gender = db.Column(db.String(1))
address = db.Column(db.String(100))
email = db.Column(db.String(50))
age = db.Column(db.Integer)
language = db.Column(db.String(5))
date_create = db.Column(db.DateTime,default=datetime.now())

def __init__(self,name,gender,address,email,age,language):
self.name = name
self.gender= gender
self.address = address
self.email = email
self.age = age
self.language = language

class ContactForm(FlaskForm):
id = HiddenField("id")
name = StringField("Name Of Student",[validators.InputRequired("Please enter your name.")])
Gender = RadioField('Gender', choices = [('M','Male'),('F','Female')])
Address = TextAreaField('Address')

email = StringField("Email",[validators.InputRequired("Please enter your email address."),validators.Email("Please enter your email address.")])
Age = IntegerField("age")
language = SelectField('language',choices=[('cpp','C++'),('py','Python')])

submit = SubmitField("Send")

@app.route('/')
def show_all():
return render_template("show12.html",contacts=ContactDAO.query.all())

@app.route("/add",methods = ['GET','POST'])
def do_add():
form1 = ContactForm()

if request.method == "POST":
if form1.validate() == False:
flash('All fields are required.')
return render_template('add12.html',form=form1)
else:
contact = ContactDAO(
form1.name.data,
form1.Gender.data,
form1.Address.data,
form1.email.data,
form1.Age.data,
form1.language.data,
)
try:
db.session.add(contact)
db.session.commit()
flash('Record was successfully added')
return redirect('/')
except Exception as e:
flash('there is an issue adding contact into db. {0}'.format(e))
return render_template('add12.html', form = form1)
elif request.method == 'GET':
return render_template('add12.html',form=form1)

@app.route('/delete/<int:id>')
def do_delete(id):
to_delete = ContactDAO.query.get_or_404(id)
try:
db.session.delete(to_delete)
db.session.commit()
return redirect('/')
except Exception as e:
flash('there is an issue delete contact into db. {0}'.format(e))
return redirect('/')

@app.route('/update/<int:id>',methods = ['POST','GET'])
def do_update(id):
form1 = ContactForm()
to_update = ContactDAO.query.get_or_404(id)

if request.method == 'GET':
form1.id.data = to_update.id
form1.name.data = to_update.name
form1.Gender.data = to_update.gender
form1.Address.data = to_update.address
form1.email.data = to_update.email
form1.Age.data = to_update.age
form1.language.data = to_update.language
return render_template('update12.html',form=form1)
elif request.method == 'POST':
to_update.id = id
to_update.name = form1.name.data
to_update.gender = form1.Gender.data
to_update.address = form1.Address.data
to_update.email = form1.email.data
to_update.age = form1.Age.data
to_update.language = form1.language.data
try:
db.session.commit()
return redirect('/')
except Exception as e:
flash('there is an issue delete contact into db. {0}'.format(e))
return redirect('/')
if __name__ == "__main__":
with app.app_context():
db.create_all()
app.run(debug=True,host='127.0.0.1',port=5000,threaded=True)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的第一个网页</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h2 style = 'text-align: center;'>Show Contact</h2>
{% with messages = get_flashed_messages() %}
{% if message %}
{% for message in messages %}
<p>{{ message }}</p>
{% endfor %}
{% endif %}
{% endwith %}
<h3>Contacts (<a href="{{ url_for("do_add") }}" target="_blank">Add Contact</a>)</h3>
<table>
<thead>
<tr>
<th>Name</th>
<th>Gender</th>
<th>Address</th>
<th>Email</th>
<th>Age</th>
<th>Language</th>
<th>Create Date</th>
<th></th>
<th></th>
</tr>
</thead>

<tbody>
{% for contact in contacts %}
<tr>
<td>{{ contact.name }}</td>
<td>{{ contact.gender }}</td>
<td>{{ contact.address }}</td>
<td>{{ contact.emal }}</td>
<td>{{ contact.age }}</td>
<td>{{ contact.date_created }}</td>
<td><a href="/update/{{contact.id}}">update</a></td>
<td><a href="/delete/{{contact.id}}">delete</a></td>
</tr>
{% endfor %}
</tbody>

</table>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的第一个网页</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h2 style="text-align: center;">Add Contact</h2>
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
<p>{{ message }}</p>
{% endfor %}
{% endif %}
{% endwith %}

{% for message in form.name.errors %}
<div>{{ message }}</div>
{% endfor %}

{% for message in form.email.errors %}
<div>{{ message }}</div>
{% endfor %}


<form action="/add" method="post">
<fieldset>
<legend>
Contact Form
</legend>
{{ form.hidden_tag() }}

<div style="font-size: 20px;font-weight: bold;margin-left: 150px;"
{{ form.name.label }}<br>
{{ form.name }}
<br>

{{ form.Gender.label }} {{ form.Gender }}
{{ form.Address.label }}<br>
{{ form.Address }}
<br>

{{ form.email.label }}<br>
{{ form.email }}
<br>

{{ form.Age.label }}<br>
{{ form.Age }}
<br>

{{ form.language.label }}<br>
{{ form.language }}
<br>
{{ form.submit }}
</div>

</fieldset>
</form>
<h3>Welcome!</h3>
</body>
</html>

Flask的Ajax包Sjiax

1
flask_sijax版本与高版本的flask不匹配

ajax

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from flask import Flask, render_template, request, jsonify

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key-here'

@app.route('/')
def index():
return """
<h1>主页</h1>
<a href='/ajax_demo'>进入AJAX测试页面</a>
"""

@app.route('/ajax_demo')
def ajax_demo():
"""AJAX演示页面"""
return render_template('ajax_example.html')

@app.route('/ajax_say_hello', methods=['POST'])
def ajax_say_hello():
"""处理AJAX打招呼请求"""
data = request.get_json()
hello_from = data.get('hello_from', '匿名')
hello_to = data.get('hello_to', '世界')

return jsonify({
'status': 'success',
'message': f'你好,从 {hello_from}{hello_to}!',
'action': 'alert'
})

@app.route('/ajax_say_goodbye', methods=['POST'])
def ajax_say_goodbye():
"""处理AJAX道别请求"""
return jsonify({
'status': 'success',
'message': '再见,无论你是谁!',
'action': 'alert'
})

if __name__ == '__main__':
app.run(debug=True, host='127.0.0.1', port=5000)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>现代AJAX测试页面</title>
<!-- 使用jQuery(可选) -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<style>
body {
font-family: Arial, sans-serif;
padding: 20px;
}
button {
margin: 10px;
padding: 10px 20px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background-color: #0056b3;
}
#result {
margin-top: 20px;
padding: 15px;
border: 1px solid #ddd;
background-color: #f9f9f9;
border-radius: 4px;
}
.success {
color: green;
}
.error {
color: red;
}
</style>
</head>
<body>
<h1>现代AJAX示例</h1>
<p>使用Fetch API进行异步JavaScript调用测试:</p>

<div>
<button onclick="sayHello()">打招呼(Fetch API)</button>
<button onclick="sayGoodbye()">道别(Fetch API)</button>
<button onclick="sayHelloJQuery()">打招呼(jQuery)</button>
</div>

<div id="result"></div>

<script>
// 使用原生Fetch API
function sayHello() {
fetch('/ajax_say_hello', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
hello_from: '张三',
hello_to: '李四'
})
})
.then(response => response.json())
.then(data => {
if (data.action === 'alert') {
alert(data.message);
}
document.getElementById('result').innerHTML =
`<p class="success">服务器响应:${data.message}</p>`;
})
.catch(error => {
console.error('Error:', error);
document.getElementById('result').innerHTML =
`<p class="error">请求失败:${error}</p>`;
});
}

function sayGoodbye() {
fetch('/ajax_say_goodbye', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
})
.then(response => response.json())
.then(data => {
if (data.action === 'alert') {
alert(data.message);
}
document.getElementById('result').innerHTML =
`<p class="success">服务器响应:${data.message}</p>`;
})
.catch(error => {
console.error('Error:', error);
document.getElementById('result').innerHTML =
`<p class="error">请求失败:${error}</p>`;
});
}

// 使用jQuery(可选)
function sayHelloJQuery() {
$.ajax({
url: '/ajax_say_hello',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({
hello_from: '王五',
hello_to: '赵六'
}),
success: function(data) {
if (data.action === 'alert') {
alert(data.message);
}
$('#result').html(`<p class="success">服务器响应:${data.message} (通过jQuery)</p>`);
},
error: function(error) {
console.error('Error:', error);
$('#result').html(`<p class="error">请求失败:${error.responseText}</p>`);
}
});
}
</script>
</body>
</html>

sijax

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from datetime import datetime

from flask import Flask, render_template,url_for,redirect,request,abort,make_response,session,flash,g
from werkzeug.wrappers.response import ResponseStream
import os
from flask_wtf import FlaskForm
from wtforms import HiddenField, StringField,IntegerField,TextAreaField,SubmitField,RadioField,SelectField
from wtforms import validators
import flask_sijax
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
path = os.path.join('.',os.path.dirname(__file__),'static/js/sijax/')
app.config["SIJAX_STATIC_PATH"] = path
app.config["SIJAX_JSON_URI"] = "/static/js/sijax/json2.js"

flask_sijax.Sijax(app)

@app.route('/')
def hello():
return "Hello World!<br /><a href='/sijax'>Go to Sijax test</a>"

@flask_sijax.route(app, '/sijax/')
def hello_sijax():
def hello_handler(obj_response,hello_from,hello_to):
obj_response.alert('Hello from %s to %s ' % (hello_from, hello_to))
obj_response.css('a','color','green')

def goodbye_handler(obj_response):
obj_response.alert('Goodbye, whoever you are.')
obj_response.css('a', 'color', 'red')

if g.sijax.is_sijax_request:
g.sijax.register_callback('say_hello',hello_handler)
g.sijax.register_callback('say_goodbye',goodbye_handler)
return g.sijax.process_request()
else:
return render_template('sijaxexample.html')

if __name__ == "__main__":
app.run(debug=True,host='127.0.0.1',port=5000,threaded=True)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的第一个网页</title>
<link rel="stylesheet" href="styles.css">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script type="text/javascript" src="/static/js/sijax/sijax.js"></script>
<script type="text/javascript">
{{ g.sijax.get_js() | safe}}
</script>
</head>
<body>
<a href="javascript://" onclick="Sijax.request('say_hello', ['zhangsan','lisi']);">
Say hello!
</a>
<a href="javascript://" onclick="Sijax.request('say_goodbye');">
Say goodbye!
</a>
</body>
</html>

request

post\get请求拿到url参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from flask import Flask,request

app = Flask(__name__)

@app.route('/',methods=['POST','GET'])
def index():
if request.method == 'GET':
print(request)
print(request.args)
print(request.args['page'])
print(request.args['pagenum'])
return "learn flask"
else:
print(request.json.get("xxx")) # request.form.get("xxx")拿到表单数据

if __name__ == '__main__':
app.run(debug=True)
1
2
3
4
5
6
7
8
浏览器访问:http://127.0.0.1:5000/?page=1&pagenum=10


后台:
<Request 'http://127.0.0.1:5000/?page=1&pagenum=10' [GET]>
ImmutableMultiDict([('page', '1'), ('pagenum', '10')])
1
10

客户端请求json

postman软件可以做get和post请求
requests库模拟客户端请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import requests
import json

# 准备要发送的数据
data = {
"name": "John Doe",
"age": 30,
"email": "john@example.com"
}

# 方法1:使用 json 参数(推荐)
response = requests.post(
'http://localhost:5000/api/data',
json=data # requests 会自动设置 Content-Type 为 application/json
)

# 方法2:使用 data 参数手动序列化
response = requests.post(
'http://localhost:5000/api/data',
data=json.dumps(data), # 手动序列化为 JSON 字符串
headers={'Content-Type': 'application/json'}
)

# 检查响应
if response.status_code == 200:
result = response.json()
print(result)
else:
print(f"Error: {response.status_code}")
javascript做模拟客户端请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 使用 Fetch API
fetch('http://localhost:5000/api/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'John Doe',
age: 30,
email: 'john@example.com'
})
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

// 使用 Axios
axios.post('http://localhost:5000/api/data', {
name: 'John Doe',
age: 30,
email: 'john@example.com'
})
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error('Error:', error);
});
curl命令行工具
1
2
3
curl -X POST http://localhost:5000/api/data \
-H "Content-Type: application/json" \
-d '{"name": "John Doe", "age": 30, "email": "john@example.com"}'

Content-Type

1
2
3
4
5
6
7
8
9
10
11
12
13
浏览器返回的数据格式(响应格式)和发送的请求格式(请求格式)是相互独立的。这是 HTTP 协议的一个重要特点。

客户端 → 服务器
请求头: Content-Type: application/json ← 我发送的是 JSON
{ "name": "Alice" }

服务器 → 客户端
响应头: Content-Type: application/json ← 我返回的也是 JSON
{ "status": "success" }

服务器 → 客户端
响应头: Content-Type: text/html ← 但我也可以返回 HTML
<html>...</html>
1
2
3
4
5
请求头: Content-Type: application/json
请求体: {"name": "Alice"}

响应头: Content-Type: application/json
响应体: {"received": {"name": "Alice"}, "status": "success"}
Content-Type: application/x-www-form-urlencoded
1
2
3
4
5
6
7
8
9
10
11
<!-- HTML 页面 -->
<form action="/submit-form" method="POST">
<input name="username" value="john">
<input name="age" value="25">
</form>

<!-- 自动发送: -->
POST /submit-form HTTP/1.1
Content-Type: application/x-www-form-urlencoded

username=john&age=25
1
request.form.get('username')
application/json
1
request.json.get('xxx')

jsonify

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from flask import jsonify

# 字典 → JSON
data = {"name": "Alice", "age": 25}
json_response = jsonify(data)
# 返回: {"name": "Alice", "age": 25}

# 列表 → JSON
items = [{"id": 1, "name": "Apple"}, {"id": 2, "name": "Banana"}]
json_response = jsonify(items)
# 返回: [{"id": 1, "name": "Apple"}, {"id": 2, "name": "Banana"}]

# 多个参数自动组合成字典
json_response = jsonify(name="Alice", age=25, city="New York")
# 返回: {"name": "Alice", "age": 25, "city": "New York"}
1
2
3
4
5
# 自动设置 Content-Type为 application/json:
response = jsonify({"message": "Success"})
print(response.headers)

# Content-Type: application/json; charset=utf-8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/api/data', methods=['POST'])
def receive_data():
# 直接获取 JSON 数据
data = request.get_json()

if not data:
return jsonify({'error': 'No JSON data provided'}), 400

# 处理数据
print(data)

return jsonify({'message': 'Data received', 'data': data}), 200

蓝图

SQLAlchemy

SQLAlchemy案例

1
对象关系映射(Object Relational Mapping,简称ORM)是一种程序设计技术,用于在面向对象编程语言和关系数据库之间进行数据转换。
1
2
3
4
5
flask-sqlalchemy
flask-mysqldb


mysql>create databasse learn_sqlalchemy default charset utf-8;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from flask import Flask

app = Flask(__name__)

class Config(object):
DEBBUG = True
SQLALCHEMY_DATABASE_URI = 'mysql://root:123456@127.0.0.1:3306/learn_sqlalchemy?charset=utf-8'

app.config.from_object(Config)
db = SQLAlchemy(app)

class Student(db.Model):
id = db.Column(db.Integer,primary_key=Ture)
name = db.Column(db.String(20))

if __name__ == "__main__":
with app.app_context():
db.create_all()
app.run()

增删改查

1
没必要记,只需要可以做这些操作就行了