Flask 学习笔记 总结

作者 : admin 本文共15234个字,预计阅读时间需要39分钟 发布时间: 2024-06-10 共2人阅读

python基础

服务端开发编程

第一个是赋值运算,第二是乘法,最后是一个是幂(即a2)
a = 2
a * 2
a ** 2

Python支持多重赋值:
a, b, c = 2, 3, 4

这句命令相当于:
a = 2
b = 3
c = 4

Python支持对字符串的灵活操作
s = ‘I like python’
s + ’ very much’ #将 s 与’ very much’拼接,得到’I like python very much’
s.split(’ ‘) #将 s 以空格分割,得到列表[‘I’, ‘like’, ‘python’]

输入 input() 函数

# 获取用户输入
user_input = input("输入你的姓名: ")
# 打印用户输入的内容
print("Hello, " + user_input + "!")

# 获取用户输入并转换为整数
age = int(input("几岁啦? "))
# 使用输入的整数值
print("我明年就要 " + str(age + 1) + " 岁啦!")

输出print() 函数

# 打印简单的字符串print("Hello, World!")
# 打印变量
name = "Alice"
print("Hello, " + name + "!")
# 使用格式化字符串
print("Hello, {}!".format(name))
# 使用 f-strings (Python 3.6+)print(f"Hello, {name}!")
# 打印多个参数
print("Hello", name, "Welcome to the Python world!")
# 打印时不换行
print("First line,", end=" ")print("Second line.")

程序基本结构(选择)

if 条件1:
	语句2
elif 条件3:
	语句4
else:
	语句5

程序基本结构(循环)

s,k = 0,0
w h i l e k < 1 0 1 : # 该 循 环 过 程 就 是 求
1+2+3+...+100
	k = k + 1
	s = s + k
print s
s = 0
for k in range(101): #该循环过程也是求1+2+3+...+100
	s = s + k
print s

程序基本结构(in语句)

s = 0
if s in range(4):
	print(u's在0, 1, 2, 3中')
if s not in range(1, 4, 1):
	print(u's不在1, 2, 3中')

Python用def来自定义函数:

def add2(x):
	return x+2
print(add2(1) )#输出结果为3

Python的函数返回值可以是各种形式,比如返回列表,甚至返回多个值:

def add2(x = 0, y = 0): #定义函数,同时定义参数的默认值
	return [x+2, y+2] #返回值是一个列表
def add3(x, y):
	return x+3, y+3 #双重返回
a, b = add3(1,2) #此时a=4,b=5

Python支持用lambda对简单的功能定义“行内函数”

f = lambda x : x + 2 #定义函数f(x)=x+2
g = lambda x, y: x + y #定义函数g(x,y)=x+y

在Python 3中,**kwargs 是一个非常有用的功能,它允许你向函数传递任意数量的关键字参数。
这些参数在函数内部作为一个字典来处理,即能够接受任意数量的参数,而不必事先知道这些参数的名称或数量。

def print_kwargs(**kwargs):
	for key, value in kwargs.items():
		print(f"{key} = {value}")
		
print_kwargs(name='Alice', age=25, city='New York')

**kwargs 与固定参数结合使用

def print_info(name, **kwargs):
	print(f"Name: {name}")
	for key, value in kwargs.items():
		print(f"{key} = {value}")
		
print_info('Bob', job='Engineer', country='USA')

Python 有四个内建的数据结构,统称为容器(container),可以是数字、字符甚至是列表,或者是它们之间几种的组合:【注意】容器里边的元素类型可以不相同。

  • List(列表)
  • Tuple(元组)
  • Dictionary(字典)
  • Set(集合)

Flask 学习笔记 总结插图

Flask 学习笔记 总结插图(1)

Flask 学习笔记 总结插图(2)

Flask 学习笔记 总结插图(2)

Flask 学习笔记 总结插图(3)

Flask 学习笔记 总结插图(4)

Flask 学习笔记 总结插图(5)

Flask 学习笔记 总结插图(6)

异常处理用try和except关键字来实现。当程序执行try块中的代码时,如果发生了异常,程序的执行将立即跳转到except块。except块允许程序对异常做出响应,而不是让程序崩溃。

while True:
	try:
		age = int(input("几岁啦? "))
		break # 如果转换成功,退出循环
	except ValueError:
		print("转换出错.")

捕捉多种异常

try:
	# 可能引发多种异常的代码
	pass
except TypeError:
	# 处理TypeError异常
	pass
except ValueError:
	# 处理ValueError异常
	pass
except (ExceptionType1, ExceptionType2) as e:
	# 同时处理两种异常,并将异常实例赋值给变量 e
	pass
except Exception as e:
	# 捕获所有非系统退出类的异常
	pass

Flask 学习笔记 总结插图(2)

Flask 学习笔记 总结插图(2)

Flask 学习笔记 总结插图(7)

Jinja2模板

Jinja2模板主要内容

  • 渲染模板、变量
  • 控制语句
  • 模板结构
  • 加载静态文件

Jinja2模板介绍

  • Jinja2 是一个现代的、设计者友好的、仿照 Django 模板的Python 模板语言。
  • 它速度快,被广泛使用,并且提供了可选的沙箱模板执行环境保证安全
  • Jinja2 需要至少 Python 2.4 版本来运行
  • pip install Jinja2 (安装Jinja2)

两种分隔符

  • 分隔符{% … %}
    • 用于执行诸如 for 循环或赋值的语句
  • 分隔符 {{ … }}
    • 表达式的结果打印到模板上

注释

  • 使用 {# … #} 注释语法

Flask 学习笔记 总结插图(8)

Flask 学习笔记 总结插图(9)

Flask 学习笔记 总结插图(10)

Flask 学习笔记 总结插图(11)

Flask 学习笔记 总结插图(2)

Flask 学习笔记 总结插图(12)

Flask 学习笔记 总结插图(2)

Flask 学习笔记 总结插图(13)

Flask 学习笔记 总结插图(2)

Flask 学习笔记 总结插图(2)

Flask 学习笔记 总结插图(14)

Flask 学习笔记 总结插图(15)

Flask 学习笔记 总结插图(16)

Flask 学习笔记 总结插图(17)

Flask 学习笔记 总结插图(18)

Flask 学习笔记 总结插图(19)

Flask 学习笔记 总结插图(20)

表单

Flask-WTF创建表单的步骤

  1. 定义表单类。决定表单中的一组字段(Field),每个Field都有对象表示,可附属一个或多个验证函数,验证函数用于验证用户提交的数据是否有效。
  2. 定义模板页面。定义HTML表单。
  3. 定义视图函数。视图函数主要是渲染表单,接收用户在表单中填写的数据。
  4. 重定向页面。作为post请求的响应(Post–>重定向–>Get模式)。

WTForms支持的HTMLField类
Flask 学习笔记 总结插图(21)Flask 学习笔记 总结插图(22)

WTForms常用验证器
Flask 学习笔记 总结插图(23)
Flask 学习笔记 总结插图(24)

EX1:“hello,xx”案例改成表单输入xx

定义表单类

Flask 学习笔记 总结插图(25)

定义模板页面

Flask 学习笔记 总结插图(26)

Bootstrap引入

  • 安装flask-bootstrap
  • 在app.py中引入Bootstrap

Flask 学习笔记 总结插图(27)

  • 在模板页中继承bootstrap的母板,并修改母板中定义的content模块

Flask 学习笔记 总结插图(28)

用户会话(session)
若要保存EX1中用户输入的名字,可考虑使用用户会话,即session[‘xx’],其中“xx”为自定义名称

Flask 学习笔记 总结插图(29)

闪现消息(flash函数)
需要让用户知道程序的状态变化,Flask内置了设置提示信息,比并传递到页面显示

Flask 学习笔记 总结插图(30)

Flask 学习笔记 总结插图(31)

数据库连接访问

使用Flask-SQLAlchemy管理数据库

在Flask-SQLAlchemy中,数据库使用URL指定

Flask 学习笔记 总结插图(32)

配置数据库

Flask 学习笔记 总结插图(33)

定义模型

模型表示应用使用的持久化实体,在ORM中,表现为一个Python类,类中的属性对应数据库表中的列

Flask 学习笔记 总结插图(34)

最常用的SQLAlchemy列类型
Flask 学习笔记 总结插图(35)
Flask 学习笔记 总结插图(36)

最常用的SQLAlchemy列的属性选项
【注意】每个模型都定义主键,一般命名为id

Flask 学习笔记 总结插图(37)

关系
关系型数据库使用关系把不同表中的行联系起来,例如,5.1案例中的关系图表示角色和用户之间存在一对多关系,即1个角色可能有多个用户。

Flask 学习笔记 总结插图(38)

常用的SQLAlchemy关系选项

Flask 学习笔记 总结插图(39)

梳理下关系类型

  • 一对多关系(多对一关系)
  • 一对一关系
  • db.relationship()中的uselist选项设置为False
  • 多对多关系
  • 需要第3张关系表(关联表或联结表),后面的课再讨论

数据库操作

  1. 插入行
  2. 修改行
  3. 删除行
  4. 查询行

Flask 学习笔记 总结插图(40)
Flask 学习笔记 总结插图(41)
Flask 学习笔记 总结插图(42)

Flask 学习笔记 总结插图(43)

Flask 学习笔记 总结插图(44)

Flask 学习笔记 总结插图(45)

常用的SQLAlchemy查询过滤器

Flask 学习笔记 总结插图(46)

常用的SQLAlchemy查询执行方法

Flask 学习笔记 总结插图(47)

后端分离开发

Flask 学习笔记 总结插图(48)

Flask 学习笔记 总结插图(49)

Flask 学习笔记 总结插图(50)

Restful API

Flask 学习笔记 总结插图(51)

Flask 学习笔记 总结插图(52)

Flask 学习笔记 总结插图(53)

Flask 学习笔记 总结插图(54)

Flask 学习笔记 总结插图(55)

Flask 学习笔记 总结插图(56)

客户端异步请求补充

Flask 学习笔记 总结插图(57)

Flask 学习笔记 总结插图(58)

Flask 学习笔记 总结插图(59)

Flask 学习笔记 总结插图(60)

Flask 学习笔记 总结插图(61)

Flask 学习笔记 总结插图(62)

Flask 学习笔记 总结插图(63)

Flask 学习笔记 总结插图(64)

跨域请求

Flask 学习笔记 总结插图(65)

Flask 学习笔记 总结插图(66)

Flask 学习笔记 总结插图(67)

Flask 学习笔记 总结插图(68)

Flask 学习笔记 总结插图(69)

Flask 学习笔记 总结插图(70)

Flask 学习笔记 总结插图(71)

Flask 学习笔记 总结插图(72)

Flask 学习笔记 总结插图(73)

图表应用

Flask 学习笔记 总结插图(74)

Flask 学习笔记 总结插图(75)

Flask 学习笔记 总结插图(76)

Flask 学习笔记 总结插图(77)

Flask 学习笔记 总结插图(78)

Flask 学习笔记 总结插图(79)

Flask 学习笔记 总结插图(80)

文件上传

Flask 学习笔记 总结插图(81)

Flask 学习笔记 总结插图(82)

Flask 学习笔记 总结插图(83)

Flask 学习笔记 总结插图(84)

Flask 学习笔记 总结插图(85)

Flask 学习笔记 总结插图(86)

Flask 学习笔记 总结插图(87)

Flask练习

练习1-1

Flask 学习笔记 总结插图(88)

代码段:

@app.route('/')
def index():
    name = request.args.get('name', '陌生人')
    return render_template('index.html', name=name)
<!DOCTYPE html>
<html>
<head>
    <title>Greeting</title>
</head>
<body>
    <h1>你好,{{ name }}</h1>
</body>
</html>

实现效果

Flask 学习笔记 总结插图(89)

练习1-2

Flask 学习笔记 总结插图(90)

Flask 学习笔记 总结插图(91)

代码片段

class User:
    def __init__(self, name, age, gender, email, interests=None):
        self.name = name
        self.age = age
        self.gender = gender
        self.email = email
        self.interests = interests if interests else []
        
@app.route('/user')
def user_view():
    # 自定义用户属性值
    user_info = {
        'name': 'ZhangSan',
        'age': 25,
        'gender': 'Female',
        'email': 'alice@example.com',
        'interests': ['reading', 'traveling', 'coding']
    }
    user = User(**user_info)
    return render_template('user.html', user=user)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>User Information</title>

<link href="http://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<div class="row">
<div class="col-md-4">
<div class="card" style="width: 18rem;">
<img class="card-img-top" src="{{ url_for('static', filename='/images/zhangsan.jpg') }}" alt="User image">
<div class="card-body">
<h5 class="card-title">{{ user.name }}</h5>
<ul class="list-unstyled">
<li><strong>年龄:</strong> {{ user.age }}</li>
<li><strong>性别:</strong> {{ user.gender }}</li>
<li><strong>EMail:</strong> {{ user.email }}</li>
<li><strong>兴趣:</strong> {{ ', '.join(user.interests) }}</li>
</ul>
<a href="#" class="btn btn-primary">联系我们</a>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card" style="width: 18rem;">
<img class="card-img-top" src="{{ url_for('static', filename='/images/zhangsan.jpg') }}" alt="User image">
<div class="card-body">
<h5 class="card-title">{{ user.name }}</h5>
<ul class="list-unstyled">
<li><strong>年龄:</strong> {{ user.age }}</li>
<li><strong>性别:</strong> {{ user.gender }}</li>
<li><strong>EMail:</strong> {{ user.email }}</li>
<li><strong>兴趣:</strong> {{ ', '.join(user.interests) }}</li>
</ul>
<a href="#" class="btn btn-primary">联系我们</a>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card" style="width: 18rem;">
<img class="card-img-top" src="{{ url_for('static', filename='/images/zhangsan.jpg') }}" alt="User image">
<div class="card-body">
<h5 class="card-title">{{ user.name }}</h5>
<ul class="list-unstyled">
<li><strong>年龄:</strong> {{ user.age }}</li>
<li><strong>性别:</strong> {{ user.gender }}</li>
<li><strong>EMail:</strong> {{ user.email }}</li>
<li><strong>兴趣:</strong> {{ ', '.join(user.interests) }}</li>
</ul>
<a href="#" class="btn btn-primary">联系我们</a>
</div>
</div>
</div>
</div>
</div>

<script src="http://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
</body>
</html>

实现效果

Flask 学习笔记 总结插图(92)

练习1-3

Flask 学习笔记 总结插图(93)

代码实现

base.html

html复制代码<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Coffee House{% endblock %}</title>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
<style>
.navbar-dark .navbar-brand {
color: #fff;
}
.navbar-dark .nav-link {
color: #fff;
}
</style>
</head>
<body>
{% include '_top.html' %}
<div class="container mt-5">
{% block content %}{% endblock %}
</div>
{% include '_footer.html' %}
<script src="http://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
</body>
</html>

_top.html

html复制代码<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="#">随缘咖啡屋</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="#">Login</a>
</li>
</ul>
</div>
</nav>

_footer.html

html复制代码<footer class="footer mt-auto py-3 bg-light">
<div class="container text-center">
<span class="text-muted">copyright© 2024 zjyivi</span>
</div>
</footer>

user_b.html

{% extends 'base.html' %}
{% block title %}王婆说媒{% endblock %}
{% block content %}
<div class="text-center my-5">
<h1>hi, {{ name }}! 欢迎光临王婆说媒</h1>
<p>祝你不在家里,就在去相亲的路上~</p>
</div>
<div class="row">
{% for i in range(3) %}
<div class="col-md-4 mb-4">
<div class="card">
<img class="card-img-top" src="{{ url_for('static', filename='/images/zhangsan.jpg') }}" alt="User image">
<div class="card-body text-center">
<h5 class="card-title">{{ user.name }}</h5>
<ul class="list-unstyled">
<li><strong>年龄:</strong> {{ user.age }}</li>
<li><strong>性别:</strong> {{ user.gender }}</li>
<li><strong>EMail:</strong> {{ user.email }}</li>
<li><strong>兴趣:</strong> {{ ', '.join(user.interests) }}</li>
</ul>
<a href="#" class="btn btn-primary">联系我们</a>
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock %}

app.py新增

@app.route('/user_b')
def user_view_b():
user_info = {
'name': '张三',
'age': 18,
'gender': '女',
'email': 'zhangsan@hznu.edu.cn',
'interests': ['游泳', '跑步', '爬山', '阅读']
}
user = User(**user_info)
name = request.args.get('name', '陌生人')
return render_template('user_b.html', user=user, name=name)

实现效果:

Flask 学习笔记 总结插图(94)

练习2

Flask 学习笔记 总结插图(95)

Flask 学习笔记 总结插图(96)

Flask 学习笔记 总结插图(97)

Flask 学习笔记 总结插图(98)

Flask 学习笔记 总结插图(99)

看看表先

Flask 学习笔记 总结插图(100)

一开始连不上

Flask 学习笔记 总结插图(101)

debug是路径问题,这里必须绝对路径

Flask 学习笔记 总结插图(102)

代码实现:

app.py

from flask import Flask, render_template, request, redirect, url_for, session, flash
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length, EqualTo
app = Flask(__name__)
app.config['SECRET_KEY'] = 'Jay17_2004_06_26'
# 绝对路径
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///'+os.path.join(basedir,'data.sqlite')
# app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)
class User:
def __init__(self, name, age, gender, email, interests=None):
self.name = name
self.age = age
self.gender = gender
self.email = email
self.interests = interests if interests else []
@app.route('/')
def index():
name = request.args.get('name', '陌生人')
return render_template('index.html', name=name)
@app.route('/user')
def user_view():
# 自定义用户属性值
user_info = {
'name': 'ZhangSan',
'age': 25,
'gender': 'Female',
'email': 'alice@example.com',
'interests': ['reading', 'traveling', 'coding']
}
user = User(**user_info)
return render_template('user.html', user=user)
@app.route('/user_b')
def user_view_b():
user_info = {
'name': '张三',
'age': 18,
'gender': '女',
'email': 'zhangsan@hznu.edu.cn',
'interests': ['游泳', '跑步', '爬山', '阅读']
}
user = User(**user_info)
name = request.args.get('name', '陌生人')
return render_template('user_b.html', user=user, name=name)
class Users(db.Model):  # 确保 Users 继承自 db.Model
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(150), unique=True, nullable=False)
password = db.Column(db.String(150), nullable=False)
class LoginForm(FlaskForm):
username = StringField('用户名', validators=[DataRequired(), Length(min=2, max=150)])
password = PasswordField('密码', validators=[DataRequired(), Length(min=6, max=150)])
submit = SubmitField('登录')
class RegistrationForm(FlaskForm):
username = StringField('用户名', validators=[DataRequired(), Length(min=2, max=150)])
password = PasswordField('密码', validators=[DataRequired(), Length(min=6, max=150)])
confirm_password = PasswordField('确认密码', validators=[DataRequired(), EqualTo('password')])
submit = SubmitField('注册')
@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = Users.query.filter_by(username=form.username.data).first()
if user and user.password == form.password.data:
session['user_id'] = user.id
session['username'] = user.username
return redirect(url_for('profile'))
else:
flash('登录信息有误!', 'danger')
return render_template('login.html', form=form)
@app.route('/register', methods=['GET', 'POST'])
def register():
form = RegistrationForm()
if form.validate_on_submit():
if len(form.username.data) < 2:
flash('用户名必须至少2位', 'danger')
elif len(form.password.data) < 6:
flash('密码必须至少6位', 'danger')
else:
user = Users.query.filter_by(username=form.username.data).first()
if user:
flash('用户名已注册', 'danger')
else:
new_user = Users(username=form.username.data, password=form.password.data)
db.session.add(new_user)
db.session.commit()
return redirect(url_for('login'))
return render_template('register.html', form=form)
@app.route('/profile')
def profile():
if 'user_id' not in session:
return redirect(url_for('login'))
return render_template('profile.html', username=session.get('username'))
@app.route('/logout')
def logout():
session.clear()
return redirect(url_for('login'))
if __name__ == '__main__':
with app.app_context():
db.create_all()  # 创建所有数据库表
app.run(debug=False)

_top.html

<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="#">王婆说媒</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="/login">Login</a>
</li>
</ul>
</div>
</nav>

base_login.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}My Site{% endblock %}</title>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
{% include '_top_login.html' %}
<div class="container mt-5">
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
{% endfor %}
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</div>
{% include '_footer.html' %}
<script src="http://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
</body>
</html>

_top_login.html

<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="/">Web服务端案例</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ml-auto">
{% if 'username' in session %}
<li class="nav-item">
<a class="nav-link" href="{{ url_for('profile') }}">{{ session.username }}</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('logout') }}">退出登录</a>
</li>
{% else %}
<li class="nav-item">
<a class="nav-link" href="{{ url_for('login') }}">登录</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('register') }}">注册</a>
</li>
{% endif %}
</ul>
</div>
</nav>

_footer.html

<footer class="footer mt-auto py-3 bg-light">
<div class="container text-center">
<span class="text-muted">copyright© 2024 Jay17</span>
</div>
</footer>

login.html

{% extends 'base_login.html' %}
{% block title %}用户登录{% endblock %}
{% block content %}
<h2 class="text-center">用户登录</h2>
<form method="POST" action="">
{{ form.hidden_tag() }}
<div class="form-group">
{{ form.username.label() }}
{{ form.username(class="form-control") }}
</div>
<div class="form-group">
{{ form.password.label() }}
{{ form.password(class="form-control") }}
</div>
<div class="form-group">
{{ form.submit(class="btn btn-primary") }}
</div>
</form>
{% endblock %}

register.html

{% extends 'base_login.html' %}
{% block title %}用户注册{% endblock %}
{% block content %}
<h2 class="text-center">用户注册</h2>
<form method="POST" action="">
{{ form.hidden_tag() }}
<div class="form-group">
{{ form.username.label() }}
{{ form.username(class="form-control") }}
</div>
<div class="form-group">
{{ form.password.label() }}
{{ form.password(class="form-control") }}
</div>
<div class="form-group">
{{ form.confirm_password.label() }}
{{ form.confirm_password(class="form-control") }}
</div>
<div class="form-group">
{{ form.submit(class="btn btn-primary") }}
</div>
</form>
{% endblock %}

profile.html

{% extends 'base_login.html' %}
{% block title %}用户中心{% endblock %}
{% block content %}
<h2 class="text-center">hello,{{ username }}!</h2>
{% endblock %}

实现效果:

/user_b路由

Flask 学习笔记 总结插图(103)

点击登录跳转至/login路由

Flask 学习笔记 总结插图(104)

登录有误一下先

Flask 学习笔记 总结插图(105)

然后再成功一下

Flask 学习笔记 总结插图(106)

点击退出登录

Flask 学习笔记 总结插图(107)

先注册一个太短的(应该是模板的原因,这边前端就被拦截了,所以就轮不到后端flash了)

Flask 学习笔记 总结插图(108)

再注册一个重复的

Flask 学习笔记 总结插图(109)

本站无任何商业行为
个人在线分享 » Flask 学习笔记 总结
E-->