【课程笔记】Python web概述及Flask介绍
一、准备工作
1.安装virtualenv
打开命令行,执行:pip list
查看当前python环境里面是否安装virtualenv,如果没有,请执行:
pip install -i virtualenv
pip install -i https://pypi.mirrors.ustc.edu.cn/simple/ virtualenv
安装完成后,再次执行pip list
查看
2.创建虚拟环境
通过上面的步骤安装成功virtualenv之后,我们就可以创建虚拟环境了:virtualenv 虚拟环境名
注意:这个命令创建虚拟环境,会在当前所在目录进行创建,如C:\Users\Smalu(电脑管理者路径),所以如果你有指定路径存放虚拟环境,请先进入该路径
cd 文件地址
再执行
virtualenv your_env_name
3.进入虚拟环境
先要进入cd到虚拟环境的位置(目录)的Scripts中,然后在激活(activate.bat)虚拟环境,则进入新建的虚拟环境中了。
cd 虚拟环境名
cd Scripts
activate
4.在上述虚拟环境中,安装Flask环境
pip install –U flask
5.安装完成以后,再次使用pip list命令查看所有安装包
6.Flask的7个外部依赖包
名称 | 功能 |
---|---|
Click(7.1.2) | 命令行工具 |
itsdangerous(1.1.0) | 提供加密和签名功能 |
Jinjia2(2.11.3) | 模板渲染引擎 |
MarkupSafe(1.1.1) | HTML字符转义(escape)工具 |
setuptools(51.3.3) | 可以帮助我们更简单的创建和分发Python包,尤其是拥有依赖关系的 |
Werkzeug(1.0.1) | WSGI工具集,处理请求与响应,内置WSGI开发服务器、调试器和重载器 |
wheel(0.36.2) | 新的 Python 的 disribution,用于替代 Python 传统的 egg 文件 |
二、编程
1.编写第一个Flask程序
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return '你好!'
if __name__ == '__main__':
app.debug = True
app.run()
ps:
有两种途径来启用调试模式。一种是直接在应用对象上设置。
app.debug = True
app.run()
另一种是作为run方法的一个参数传入。
app.run(debug=True)
2.Flask 路由
from flask import Flask, views, redirect, url_for
app = Flask(__name__)
# 路由
@app.route('/hello1')
def hello1():
return '第一种路由写法'
@app.route('/hello2')
def hello2():
return '第二种路由写法'
app.add_url_rule('/hello2', 'h2', hello2, methods=['GET'])
if __name__ == '__main__':
app.debug = True
app.run()
运行:
[127.0.0.1:5000/hello1](http://127.0.0.1:5000/hello1)
tips:
1.黄色波浪线:代码靠得太近,一般空两行。
2.运行没效果:注意是不是运行到别的文件。
3.Flask 变量规则
from flask import Flask, views, redirect, url_for
app = Flask(__name__)
@app.route('/hello/<name>') # 变量name默认值是str
def hello_name(name):
return 'Hello %s!' % name
@app.route('/blog/<int:postID>')
def show_blog(postID):
return 'Blog Number is %d' % postID
@app.route('/rev/<float:revNo>')
def revision(revNo):
return 'Revision Number %.2f' % revNo
@app.route('/showany/<path:special_str>') # special_str允许存在/这种有歧义的字符
def showAnyInfo(special_str):
return "I can show any info ,such as '%s'" % special_str
if __name__ == '__main__':
app.debug = True
app.run()
运行:
http://localhost:5000/hello/chen
http://localhost:5000/blog/5
http://localhost:5000/rev/0.68
http://localhost:5000/showany/shenm/%E8%80%8C%E9%9D%9Ee
4.为视图绑定多个URL
from flask import Flask, views, redirect, url_for
app = Flask(__name__)
@app.route('/')
@app.route('/index')
def index():
return "Welcome to Flask"
if __name__ == '__main__':
app.debug = True
app.run()
运行:
http://localhost:5000
http://localhost:5000/index
5.构造 URL
from flask import Flask, views, redirect, url_for, render_template
app = Flask(__name__)
# 3.2构造url
@app.route('/post/<int:post_id>')
def show_post(post_id):
print(post_id)
return f'文章的id:{post_id}'
# 绑定url
@app.route('/url/')
def redirect_to_url():
# 跳转到show_post视图函数
return url_for('show_post', post_id=10)
if __name__ == '__main__':
app.debug = True
app.run()
6.HTTP方法
序号 | 方法与描述 |
---|---|
1 | GET, 以未加密的形式将数据发送到服务器。最常见的方法。 |
2 | HEAD, 和GET方法相同,但没有响应体。 |
3 | POST, 用于将HTML表单数据发送到服务器。POST方法接收的数据不由服务器缓存。 |
4 | PUT, 用上传的内容替换目标资源的所有当前表示。 |
5 | DELETE, 删除由URL给出的目标资源的所有当前表示。 |
(1)login.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/login" method = "post">
<p>Enter Name:</p>
<input type="text" name="name"/>
<p>Enter Password:</p>
<input type="password" name="passwd"/>
<p><input type="submit" value="登录"/></p>
</form>
</body>
</html>
(2)app.py 【写法1】
from flask import Flask, views, redirect, url_for, request, render_template
app = Flask(__name__)
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST': # 请求方式为POST
# 拿到表单提交过来的用户数据:
name = request.form['name']
passwd = request.form['passwd']
if name=='nacy' and passwd=='123':
return '恭喜,登录成功!'
else:
return '不好意思,登录失败!'
else: # 默认请求方式为GET
return render_template('login.html')
if __name__ == '__main__':
app.debug = True
app.run()
# app.add_url_rule(rule=访问的url,endpoint=路由别名,view_func=视图名称,methods=[允许访问的方法])
# app.run(host='0.0.0.0', port=8000, debug=True)
(3)app.py【写法2】
from flask import Flask, views, redirect, url_for, request, render_template
app = Flask(__name__)
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST': # 请求方式为POST
# 拿到表单提交过来的用户数据:
return do_the_login()
else: # 默认请求方式为GET
return show_the_login_form()
def do_the_login():
name = request.form['name']
passwd = request.form['passwd']
if name == 'nacy' and passwd == '123':
return '恭喜,登录成功!'
else:
return '不好意思,登录失败!'
def show_the_login_form():
return render_template('login.html')
if __name__ == '__main__':
app.debug = True
app.run()
# app.add_url_rule(rule=访问的url,endpoint=路由别名,view_func=视图名称,methods=[允许访问的方法])
# app.run(host='0.0.0.0', port=8000, debug=True)
7.模板-渲染模板
(1)index.html
Welcome to Flask
(2)user.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>Hello, {{ name }}!</h1>
</body>
</html>
(3)hello.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>我是模板</h2>
{{ my_int }}
<br>
{{ my_str }}
<br>
{{ my_array }}
<br>
{{ my_dict }}
<hr>
<h2>模板的list数据获取</h2>
<hr>
{{ my_array[0] }}
<br>
{{ my_array.1 }}
<hr>
<h2>字典数据获取</h2>
<hr>
{{ my_dict['name'] }}
<br>
{{ my_dict.age }}
<hr>
<h2>算术运算</h2>
<br>
{{ my_array.0 + 10 }}
<br>
{{ my_array[0] + my_array.1 }}
</body>
</html>
(4)student
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="http://localhost:5000/result" method="POST">
<p>Name <input type = "text" name = "Name" /></p>
<p>Physics <input type = "text" name = "Physics" /></p>
<p>Chemistry <input type = "text" name = "Chemistry" /></p>
<p>Maths <input type ="text" name = "Mathematics" /></p>
<p><input type = "submit" value = "submit" /></p>
</form>
</body>
</html>
(5)result
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Title</title>
</head>
<body>
<table border = 1>
{% for key, value in result.items() %}
<tr>
<th> {{ key }} </th>
<td> {{ value }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
(6)app.py
from flask import Flask, views, redirect, url_for, request, render_template
app = Flask(__name__)
# @app.route('/')
# def index():
# # 渲染模板
# return render_template('index.html')
@app.route('/user/<username>') # 将参数传递到html页面
def show_user_profile(username):
# 显示该用户名的用户信息
return render_template('user.html', name=username) # 渲染模板
@app.route('/hello')
def hello():
# 往模板中传入的数据
my_str = 'Hello Word'
my_int = 10
my_array = [3, 4, 2, 1, 7, 9]
my_dict = {
'name': '李华',
'age': 18
}
return render_template('hello.html',
my_str=my_str,
my_int=my_int,
my_array=my_array,
my_dict=my_dict)
@app.route('/student')
def student_info():
return render_template('student.html')
@app.route('/result', methods=['GET', 'POST'])
def student_result():
# 客户端提交给服务器的request请求,都被放在服务器的request中,使用的时候,需要从request中获取数据
if request.method == 'POST':
# 第一种方式:将数据从request.form表单中取出
# name = request.form['Name']
# physics = request.form['Physics']
# chemistry = request.form['Chemistry']
# mathematics = request.form['Mathematics']
# result = {'Name':name,'Physics':physics,'Chemistry':chemistry,'Mathematics':mathematics}
# print(request.form)
# return render_template('result.html', result=result)
# 第二种方式:form表单本身就是一个字典,所以可以直接传递
return render_template('result.html', result=request.form)
if __name__ == '__main__':
app.debug = True
app.run()
注意:methods=[‘GET’, ‘POST’] 两种方式
运行:
http://127.0.0.1:5000
http://127.0.0.1:5000/user/chen
http://127.0.0.1:5000/hello
http://127.0.0.1:5000/student
8.Flask 消息闪现
(1)index.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Title</title>
</head>
<body>
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
<p>{{ message }}</p>
{% endfor %}
{% endif %}
{% endwith %}
<h3>欢迎来到登录界面!</h3>
<a href = "{{ url_for('login') }}">login</a>
</body>
</html>
(2)login.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Title</title>
</head>
<body>
<form method = "post" action = "http://localhost:5000/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>错误</strong>: {{ error }}</p>
{% endif %}
</body>
</html>
(3)app.py
from flask import Flask, redirect, url_for, request, session, render_template, abort, flash
app = Flask(__name__)
# 如果app.secret_key未设置,则Flask将不允许你设置或访问会话字典。
app.secret_key = 'fsvgfsvfvfvfdbgdada' # 随机,长度不限,唯一即可
@app.route('/')
def index():
return render_template('index.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != 'admin' or request.form['password'] != 'admin':
error = '您输入的用户名或密码错误,请重新输入!'
else:
flash('登录成功!')
return redirect(url_for('index'))
return render_template('login.html', error=error)
if __name__ == '__main__':
app.debug = True
app.run()
运行:
http://127.0.0.1:5000
http://127.0.0.1:5000/login
9.Flask重定向(redirect)和错误
(1)login.html
(2)app.py
from flask import Flask, redirect, url_for, request, session, render_template, abort
app = Flask(__name__)
@app.route('/')
def index():
return render_template('login.html')
@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)
else:
return redirect(url_for('index'))
@app.route('/success')
def success():
return 'logged in successfully'
if __name__ == '__main__':
app.debug = True
app.run()
'''
Flask类具有带有错误代码的abort()函数: Flask.abort(code)
code参数采用以下值之一:
400 - 用于错误请求
401 - 用于未身份验证的
403 - Forbidden
404 - 未找到
406 - 表示不接受
415 - 用于不支持的媒体类型
429 - 请求过多
'''
10.模板中显示使用过滤器的变量
(1)常用过滤器
名称 | 说明 |
---|---|
safe | 渲染值时禁用字符转义,很适合显示变量中存储的HTML代码 |
capitalize | 字符串第一个字母大写,其他都小写 |
lower | 把值转换成小写形式 |
upper | 把值转换成大写形式 |
title | 字符串内若有多个单词,所有单词的首字母大写 |
trim | 把值的首尾空格去掉 |
striptags | 渲染之前把值中所有的 HTML 标签都删掉 |
(2)test_filter.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta charset="UTF-8">
<title>Jinja2 Filter</title>
</head>
<body>
<p style="color: blue"> {{ 'Hello Jinja2 !' | reverse }} </p>
<br/><p style="color: pink"> {{ data.keys() | upper }} </p>
<br/><p style="color: aqua"> {{ data.values() | lower}}</p>
{% for key in data.keys() %}
<div>
<p style="color: rebeccapurple"> {{ '%s : %s' | format(key, data[key]) }} </p>
</div>
{% endfor %}
{{ SomePath['SomePath'] | safe | truncate(200, True)}}
<br/><p style="color: blue"> {{ data.keys() | first | upper }} </p>
{% filter upper %}
python 碎片<br/>
{{ data }}
{% endfilter %}
</body>
</html>
(3)test_filter2.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Title</title>
</head>
<body>
{% set name='nacy.Shan' %}
{# 输出大写 #}
<h1>hello, {{ name|upper }}!</h1>
{# 输出大写,超过3个字符打断,用'...'替代 #}
<h1>hello, {{ name|upper|truncate(3,True) }} !</h1>
{# 当变量未定义时,显示默认字符串,可以缩写为d #}
{{ name | default('No name', true) }} <br />
{{ new_name | d('No new_name ', true) }} <br />
{# 单词首字母大写 #}
{{ 'hello' | capitalize }} <br />
{# 单词全小写 #}
{{ 'XML' | lower }} <br />
{# 去除字符串前后的空白字符 #}
{{ ' hello ' | trim }} <br />
{# 字符串反转,返回"olleh" #}
{{ 'hello' | reverse }} <br />
{# 格式化输出,返回"Number is 2" #}
{{ '%s is %d' | format("Number", 2) }} <br />
{# 关闭HTML自动转义 #}
{{ '<em>name</em>' | safe }} <br />
{# 四舍五入取整,返回13.0 #}
{{ 12.8888 | round }} <br />
{# 向下截取到小数点后2位,返回12.88 #}
{{ 12.8888 | round(2, 'floor') }} <br />
{# 绝对值,返回12 #}
{{ -12 | abs }} <br />
{# 取第一个元素 #}
{{ [1,2,3,4,5] | first }} <br />
{# 取最后一个元素 #}
{{ [1,2,3,4,5] | last }} <br />
{# 返回列表长度,可以写为count #}
{{ [1,2,3,4,5] | length }} <br />
{# 列表求和 #}
{{ [1,2,3,4,5] | sum }} <br />
{# 列表排序,默认为升序 #}
{{ [3,2,1,5,4] | sort }} <br />
{# 合并为字符串,返回"1 | 2 | 3 | 4 | 5" #}
{{ [1,2,3,4,5] | join(' | ') }} <br />
{# 列表中所有元素都全大写。这里可以用upper,lower,但capitalize无效 #}
{{ ['tom','bob','ada'] | upper }} <br />
{# 字典操作 #}
{# {% set users=[{'name':'Tom','gender':'M','age':20},#}
{# {'name':'John','gender':'M','age':18},#}
{# {'name':'Mary','gender':'F','age':24},#}
{# {'name':'Bob','gender':'M','age':31},#}
{# {'name':'Lisa','gender':'F','age':19}]#}
{# %}#}
{# 按指定字段排序,这里设reverse为true使其按降序排 #}
<ul>
{% for user in users | sort(attribute='age', reverse=true) %}
<li>{{ user.name }}, {{ user.age }}</li>
{% endfor %}
</ul>
{# 列表分组,每组是一个子列表,组名就是分组项的值 #}
<ul>
{% for group in users|groupby('gender') %}
<li>{{ group.grouper }}
<ul>
{% for user in group.list %}
<li>{{ user.name }}</li>
{% endfor %}</ul>
</li>
{% endfor %}
</ul>
{# 取字典中的某一项组成列表,再将其连接起来 #}
{{ users | map(attribute='name') | join(', ') }}
</body>
</html>
(4)other.py
class User(object):
def __init__(self, name, age, gender='male'):
self.name = name
self.age = age
self.gender = gender
def __str__(self):
return 'name: ' + self.name + ', age: ' + self.age + ', gender:' + self.gender
(5)app.py
from flask import Flask, views, redirect, url_for, request, render_template
from other import User
app = Flask(__name__)
@app.route('/test_filter')
def test_flask_filter():
data = {
'Python': '编程语言',
'Flask': 'Web 框架',
'Jinja2': '模板引擎',
'HTML': '前端语言'
}
SomePath = {'SomePath': '<h1 style="color:red">SomePath</h1>'}
return render_template('test_filter.html', data=data, SomePath=SomePath)
@app.route('/test_filter2')
def test_flask_filter2():
user1 = User('nacy', 18, 'female')
print(type(user1))
print(user1.name)
print(user1.age)
print(user1.gender)
user2 = User('bill', 28, 'male')
user3 = User('jack', 20, 'male')
user4 = User('lily', 25, 'female')
users = [user1, user2, user3, user4]
return render_template('test_filter2.html', users=users)
if __name__ == '__main__':
app.debug = True
app.run()
# app.add_url_rule(rule=访问的url,endpoint=路由别名,view_func=视图名称,methods=[允许访问的方法])
# app.run(host='0.0.0.0', port=8000, debug=True)
运行:
http://127.0.0.1:5000/test_filter
http://127.0.0.1:5000/test_filter2
11.模板碎片化灵活处理
(1)base.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
{% block head %}
<title>
{% block title %}{% endblock %} - My Application
</title>
{% endblock %}
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html>
(2)index.html
{% extends 'base.html' %}
{% block title %}Index{% endblock %}
{% block head %}
{{ super() }}
<style>
body{
background-color: aqua;
}
</style>
{% endblock %}
{% block body %}
<h1>Hello, World!</h1>
{% endblock %}
(3)app.py
from flask import Flask, views, redirect, url_for, request, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
app.debug = True
app.run()
运行:
http://127.0.0.1:5000/
12.Flask Cookies
(1)关于Cookies
Cookie以文本文件的形式存储在客户端的计算机上。其目的是记住和跟踪与客户使用相关的数据,以获得更好的访问者体验和网站统计信息。Request对象包含Cookie的属性。它是所有cookie变量及其对应值的字典对象,客户端已传输。除此之外,cookie还存储其网站的到期时间,路径和域名。
在Flask中,对cookie的处理步骤为:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eoSRdHQp-1658367070106)(C:\Users\s7980\AppData\Roaming\Typora\typora-user-images\image-20220710235535026.png)]
(2)index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>cookies——index</title>
</head>
<body>
{% if set_ok %}
{# 之前没有cookie,初次访问此页面,我向浏览器写入了cookie #}
恭喜,设置cookie成功!
{% else %}
{# 取cookies的值并显示出来吧 #}
{% for key,value in cookies.items() %}
{{ key }} : {{ value }} <br />
{% else %}
还没有可取的cookie
{% endfor %}
{% endif %}
</body>
</html>
(3)app.py
from flask import Flask, request, make_response, render_template
app = Flask(__name__)
# 4.1-2 flask Cookie和Session
@app.route('/')
def hello_world():
# return 'hello flask'
return '你好,欢迎学习flask'
@app.route('/set_cookie')
def set_cookies():
resp = make_response(render_template('index.html', set_ok=True)) # 设置响应体
resp.set_cookie('暨大', '学生', max_age=3600)
resp.set_cookie('靓仔', '张三', max_age=3600)
resp.set_cookie('靓女', '慕容', max_age=3600)
return resp
@app.route('/get_cookie')
def get_cookie():
# 从 request中 获取cookies信息
cookies = request.cookies
return render_template('index.html', cookies=cookies)
@app.route('/del_cookie/<cookiename>')
def del_cookie(cookiename):
# 设置响应体
resp = make_response(f'删除cookie:"{cookiename}"成功')
resp.delete_cookie(cookiename)
cookie = request.cookies
print(cookie)
return resp
if __name__ == '__main__':
# app.config['DEBUG'] = True
app.debug = True
app.run()
运行:
http://127.0.0.1:5000/set_cookie
http://127.0.0.1:5000/get_cookie
http://127.0.0.1:5000/del_cookie/%E5%BC%A0%E4%B8%89
13.Flask Sessions
(1)关于Sessions
与Cookie不同,Session(会话)数据存储在服务器上。会话是客户端登录到服务器并注销服务器的时间间隔。需要在该会话中保存的数据会存储在服务器上的临时目录中。
为每个客户端的会话分配会话ID。会话数据存储在cookie的顶部,服务器以加密方式对其进行签名。对于此加密,Flask应用程序需要一个定义的SECRET_KEY。
Session对象也是一个字典对象,包含会话变量和关联值的键值对。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q1QpeLyS-1658367070109)(C:\Users\s7980\AppData\Roaming\Typora\typora-user-images\image-20220711000229333.png)]
(2)app.py
from flask import Flask, request, session, redirect, url_for
app = Flask(__name__)
app.secret_key = 'sabdjanjdsajkbdja27234737237' # 设置随机的秘钥,长度随意
# 4.3 Session
@app.route('/')
def index():
if 'name' in session:
name = session['name']
return '登录用户名是:' + name + '<br>' + \
"<b><a href = '/logout'>点击这里注销</a></b>"
# return '<h1 style="color : red">你好,欢迎学习flask</h1>'
return "您暂未登录, <br>" \
"<a href = '/login'></b>" + "点击这里登录</b></a>"
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
session['name'] = request.form['username']
return redirect(url_for('index'))
'''
return '<form action="/login" method="post">' \
'<a>用户名:<input name="username" type="text"></a><br>' \
'<a>密码:<input name="password" type="text"></a><br>' \
'<a><input name="login" type="submit" value="登录"></a>' \
'</form>'
'''
return '''<form action = "" method = "post">
<p><input type="text" name="username"/></p>
<p><input type="submit" value="登录"/></p>
</form>'''
@app.route('/logout')
def logout():
session.pop('name',None)
return redirect(url_for('index'))
if __name__ == '__main__':
# app.config['DEBUG'] = True
app.debug = True
app.run()
附录.登录注册功能尝试
1.深入理解 get 模式
(1)http_get_test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Get</title>
</head>
<body>
<a>username:{{name}}</a><br>
<a>password:{{pwd}}</a>
</body>
</html>
(2)【第一种】app.py
from flask import Flask, request, url_for
app = Flask(__name__)
@app.route('/get')
def get():
print(request)
username = request.args.get('user')
password = request.args.get('pwd')
return f'url获取到的信息是:{username, password}'
if __name__ == '__main__':
app.debug = True
app.run()
(3)【第二种】app.py
from flask import Flask, request, render_template, redirect, url_for
app = Flask(__name__)
# 3.3 HTTP get方法和post方法
@app.route('/')
def index():
return 'hello flask'
# 3.3.1 url 获取参数/url传参的方式
# 第1种
@app.route('/get_test/<args>')
def getargs(args):
print(args)
return f'获取到的args是:{args}'
# 第2种
@app.route('/get_test')
def get():
print(request)
username = request.args.get('user')
password = request.args.get('pwd')
# return f'url获取到的信息是:{username, password}'
return render_template('http_get_test.html', name=username, pwd=password)
if __name__ == '__main__':
app.debug = True
app.run()
运行:
http://127.0.0.1:5000/
http://127.0.0.1:5000/get_test?user=admin&pwd=111
http://127.0.0.1:5000/register_test
2.深入理解post模式
(1) http_register_test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>POST</title>
</head>
<body>
<form action="/register_test" method="post">
<a>用户名:<input name="username" type="text"></a><br>
<a>密码:<input name="password" type="text"></a><br>
<a><input name="add" type="submit" value="注册"></a>
</form>
</body>
</html>
(2)http_register_success.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册成功</title>
</head>
<body>
<form method="post">
<a>注册成功!</a><br>
<a>用户名:<input name="username" type="text"></a><br>
<a>密码:<input name="password" type="text"></a><br>
<a><input name="login" type="submit" value="登录"></a>
</form>
</body>
</html>
(3)app.py
from flask import Flask, request, render_template, redirect, url_for
app = Flask(__name__)
# USER = [{'username': '张三', 'password': '123'}]
# USER = [{'username': '张三', 'password': '123'},
# {'username': '李四', 'password': '1234'},
# {'username': '王五', 'password': '12345'}]
USER = []
# 3.3.2 POST方法
# 3.3.2.1 模拟注册功能
@app.route('/register_test', methods=['GET', 'POST'])
def post():
if request.method == 'POST':
user = request.form.get('username')
pwd = request.form['password']
print(user, pwd)
USER.append({'username': user, 'password': pwd})
print(USER)
# return f'用户:{user}, 密码:{pwd}'
return render_template('http_register_success.html', username=user, password=pwd)
else:
return render_template('http_register_test.html')
if __name__ == '__main__':
app.debug = True
app.run()
运行:
http://127.0.0.1:5000/register_test
3.综合运用
(1)http_get_test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Get</title>
</head>
<body>
<a>username:{{name}}</a><br>
<a>password:{{pwd}}</a>
</body>
</html>
(2)http_login_success_test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录成功</title>
</head>
<body>
<p>login success</p>
<p>恭喜登录成功</p>
<a>用户名:{{username}}</a><br>
<a>密码:{{password}}</a>
</body>
</html>
(3)http_login_test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<form action="/login" method="post">
<a>用户名:<input name="username" type="text"></a><br>
<a>密码:<input name="password" type="text"></a><br>
<a><input name="login" type="submit" value="登录"></a>
</form>
</body>
</html>
(4)http_register_success.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册成功</title>
</head>
<body>
<p>register success</p>
<p>注册成功</p>
<a>用户名:{{username}}</a><br>
<a>密码:{{password}}</a>
</body>
</html>
(5)http_register_test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
</head>
<body>
<form action="/register_test" method="post">
<a>用户名:<input name="username" type="text"></a><br>
<a>密码:<input name="password" type="text"></a><br>
<a><input name="login" type="submit" value="注册"></a>
</form>
</body>
</html>
(6)app.py
from flask import Flask, request, render_template, redirect, url_for
app = Flask(__name__)
# 3.3 HTTP get方法和post方法
@app.route('/')
def index():
return 'hello flask'
# 3.3.1 url 获取参数/url传参的方式
# 第1种
@app.route('/get_test/<args>')
def getargs(args):
print(args)
return f'获取到的args是:{args}'
# 第2种
@app.route('/get_test')
def get():
print(request)
username = request.args.get('user')
password = request.args.get('pwd')
# return f'url获取到的信息是:{username, password}'
return render_template('http_get_test.html', name=username, pwd=password)
# USER = [{'username': '张三', 'password': '123'}]
# USER = [{'username': '张三', 'password': '123'},
# {'username': '李四', 'password': '1234'},
# {'username': '王五', 'password': '12345'}]
USER = []
# 3.3.2 POST方法
# 3.3.2.1 模拟注册功能
@app.route('/register_test', methods=['GET', 'POST'])
def post():
if request.method == 'POST':
user = request.form.get('username')
pwd = request.form['password']
print(user, pwd)
USER.append({'username': user, 'password': pwd})
print(USER)
# return f'用户:{user}, 密码:{pwd}'
return render_template('http_register_success.html', username=user, password=pwd)
else:
return render_template('http_register_test.html')
# 3.3.2.2 模拟登录功能
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
# 从form 表单中获取提交的登录数据, 两种方法都可以
user = request.form.get('username')
pwd = request.form['password']
'''
判断用户登录是否成功
if user != '张三' or pwd != '123':
return '用户名或密码错误,请重新输入!'
else:
return '登录成功'
'''
print(USER)
if {'username': user, 'password': pwd} not in USER:
return '用户名或密码错误,请重新输入!'
else:
return render_template('http_login_success_test.html', username=user, password=pwd)
# 使用的是假数据,所以这里要先判断USER是否为空
else:
return render_template('http_login_test.html')
if __name__ == '__main__':
app.debug = True
app.run()
运行:
http://127.0.0.1:5000/
http://127.0.0.1:5000/get_test?user=admin&pwd=111
http://127.0.0.1:5000/register_test
http://127.0.0.1:5000/login