Flask 学习笔记 总结

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(集合)

image-20240513233410965

image-20240513233425493

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

image-20240513233507105

image-20240513233518989

image-20240513233532447

image-20240513233541600

异常处理用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

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

image-20240513233723341

Jinja2模板

Jinja2模板主要内容

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

Jinja2模板介绍

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

两种分隔符

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

注释

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

image-20240513234002592

image-20240513234046959

image-20240513234056396

image-20240513234108376

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

image-20240513234128460

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

image-20240513234151101

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

image-20240513234229621

image-20240513234242731

image-20240513234250272

image-20240513234303226

image-20240513234317975

image-20240513234326390

image-20240513234334881

表单

Flask-WTF创建表单的步骤

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

WTForms支持的HTMLField类
image-20240520220918924image-20240520220931291

WTForms常用验证器
image-20240520220953361
image-20240520221004626

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

定义表单类

image-20240527231945045

定义模板页面

image-20240527232007769

Bootstrap引入

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

image-20240520221252408

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

image-20240520221319660

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

image-20240527232033334

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

image-20240527232059733

image-20240520222133242

数据库连接访问

使用Flask-SQLAlchemy管理数据库

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

image-20240527232205539

配置数据库

image-20240527232216823

定义模型

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

image-20240520222827586

最常用的SQLAlchemy列类型
image-20240527232234595
image-20240527234022733

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

image-20240527234038326

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

image-20240520223019638

常用的SQLAlchemy关系选项

image-20240527234112337

梳理下关系类型

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

数据库操作

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

image-20240520223126920
image-20240520223135293
image-20240520223149751

image-20240520223159200

image-20240520223207430

image-20240520223215336

常用的SQLAlchemy查询过滤器

image-20240527234143640

常用的SQLAlchemy查询执行方法

image-20240527234156831

前后端分离开发

image-20240527234337090

image-20240527234352333

image-20240527234403460

Restful API

image-20240527234416642

image-20240527234434625

image-20240527234442730

image-20240527234451444

image-20240527234501086

image-20240527234508222

客户端异步请求补充

image-20240527234525680

image-20240527234533366

image-20240527234540226

image-20240527234557262

image-20240527234606163

image-20240527234615683

image-20240527234626058

image-20240527234640052

跨域请求

image-20240527234653805

image-20240527234701449

image-20240527234711170

image-20240527234721317

image-20240527234729206

image-20240527234742804

image-20240527234751799

image-20240527234759473

image-20240527234808613

图表应用

image-20240527234845676

image-20240527234852881

image-20240527234859524

image-20240527234907486

image-20240527234916667

image-20240527234925347

image-20240527234935381

文件上传

image-20240527235026404

image-20240527235034431

image-20240527235041687

image-20240527235050484

image-20240527235057790

image-20240527235105062

image-20240527235114014

Flask练习

练习1-1

image-20240602161822423

代码段:

@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>

实现效果

image-20240602162035494

练习1-2

image-20240602161839220

image-20240602161845496

代码片段

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>
    <!-- Bootstrap CSS -->
    <link href="https://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>

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

实现效果

image-20240602173737645

练习1-3

image-20240602174154303

代码实现

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="https://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="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"></script>
    <script src="https://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)

实现效果:

image-20240602175410972

练习2

image-20240602175704599

image-20240602175714051

image-20240602175951854

image-20240602180001484

image-20240602180012347

看看表先

image-20240602182855304

一开始连不上

image-20240602185538669

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

image-20240602185554509

代码实现:

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="https://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">&times;</span>
                        </button>
                    </div>
                {% endfor %}
            {% endif %}
        {% endwith %}
        {% block content %}{% endblock %}
    </div>

    {% include '_footer.html' %}

    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"></script>
    <script src="https://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路由

image-20240602181250127

点击登录跳转至/login路由

image-20240602181307886

登录有误一下先

image-20240602185631049

然后再成功一下

image-20240602185649776

点击退出登录

image-20240602185714107

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

image-20240602190133681

再注册一个重复的

image-20240602185929147

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/682958.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网络编程(一)

网络编程&#xff08;一&#xff09; 网络基础网络体系结构**OSI的7层模型**&#xff1a;&#xff08;理想化&#xff09;**每层的功能** **TCP/IP的4层模型**&#xff1a;&#xff08;在使用&#xff09;常见的协议IP地址IPV4分类A类&#xff08;第1位固定为0&#xff09;B类&…

10个令人惊叹的Python自动化脚本

大家好&#xff0c;Python凭借其简单和通用性&#xff0c;能够为解决每天重复同样的工作提供最佳方案。本文将介绍10个Python自动化脚本&#xff0c;可以帮助自动化完成任务&#xff0c;提高工作效率&#xff0c;它们可以成为项目运行中的便捷工具&#xff0c;可以收藏这些脚本…

conflicting types for 错误问题

操作系统真象还原中&#xff0c;第十一章出现的问题&#xff1a; 怎样编译都会出现一个conflicting types for ’xxx‘的错误 出现这个错误的原因&#xff1a; 头文件声明和定义参数稍有不同 头文件中声明 void Hanlder(const char * buf); 在定义时写作 void Hanlder(char…

C# WPF入门学习主线篇(六)—— TextBox常见属性和事件

欢迎回到C# WPF入门学习系列的第六篇。在前面的文章中&#xff0c;我们探讨了按钮&#xff08;Button&#xff09;的事件处理。今天&#xff0c;我们将继续学习另一个常用的WPF控件——TextBox。本文将介绍 TextBox 的常见属性和事件&#xff0c;并通过示例代码展示如何在实际应…

用这个AI工具,做公众号爆款图文,5分钟一篇10w+,居然这么简单!(附工具教程)

文章首发于公众号&#xff1a;X小鹿AI副业 大家好&#xff0c;我是程序员X小鹿&#xff0c;前互联网大厂程序员&#xff0c;自由职业2年&#xff0c;也一名 AIGC 爱好者&#xff0c;持续分享更多前沿的「AI 工具」和「AI副业玩法」&#xff0c;欢迎一起交流~ 之前X小鹿一直在各…

泵制造5G智能工厂工业物联数字孪生可视化,推进制造业数字化转型

泵制造5G智能工厂工业物联数字孪生可视化&#xff0c;推进制造业数字化转型。泵制造行业&#xff0c;作为工业领域的核心部分&#xff0c;更是急需通过技术创新实现生产流程的智能化和高效化。而5G智能工厂工业物联数字孪生可视化技术的出现&#xff0c;为泵制造业的数字化转型…

代码随想录算法训练营第四十四天 | 01背包问题理论基础、01背包问题滚动数组、416. 分割等和子集

背包问题其实有很多种&#xff0c;01背包是最基础也是最经典的&#xff0c;软工计科学生一定要掌握的。 01背包问题 代码随想录 视频讲解&#xff1a;带你学透0-1背包问题&#xff01;| 关于背包问题&#xff0c;你不清楚的地方&#xff0c;这里都讲了&#xff01;| 动态规划经…

YOLO10:手把手安装教程与使用说明

目录 前言一、YOLO10检测模型二、YOLO安装过程1.新建conda的环境 yolo10安装依赖包测试 总结 前言 v9还没整明白&#xff0c;v10又来了。而且还是打败天下无敌手的存在&#xff0c;连最近很火的RT-DETR都被打败了。那么&#xff0c;笑傲目标检测之林的v10又能持续多久呢&#…

2024第三届全国大学生数据分析大赛,有没有没有思路的朋友?

大家好呀&#xff0c;2024第三届全国大学生数据分析大赛准备开始咯&#xff0c;大家是不是没有思路呀。 本论文可以保证原创&#xff0c;保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半成品论文。 比赛现在还能报名哈&#xff01;6-7才截…

图像背景去除工具:removebg

文章目录 简介面向不同用户价格 简介 removebg&#xff0c;就是remove background&#xff0c;是一款智能图片背景去除工具。 在免费使用时&#xff0c;用到的是本地的CPU。我第一次试用时&#xff0c;图片刚上传之后&#xff0c;电脑的帧率便直线下降&#xff0c;鼠标都拖不…

买视觉检测设备需要多少钱?

随着工业自动化的发展&#xff0c;其应用范围逐步提高&#xff0c;其中母子图像传感器、CMOS和CCD摄像机、DSP、ARM嵌入式技术、图像处理和模式识别技术的快速发展&#xff0c;有效地推动了视觉检测设备的发展。在机器视觉领域中&#xff0c;常见的就是视觉检测、视觉识别、视觉…

Win11中Yolo V10安装过程记录

1. 配置Anaconda环境&#xff1a; conda create -n yolov10 python3.9 conda activate yolov10 pip install -r requirements.txt pip install -e . 这里由于torch2.0.1太慢&#xff0c;单独用pytorch官网安装流程&#xff08;选择支持GPU版本&#xff09;&#xff1a; con…

数据治理挑刺行动:深化治理,提升数据质量

在当今信息化社会&#xff0c;数据已经成为推动经济发展、社会进步的重要驱动力。然而&#xff0c;随着数据量的爆炸式增长&#xff0c;数据质量问题也日益凸显&#xff0c;给各行各业带来了不小的挑战。为了应对这一挑战&#xff0c;深化数据治理&#xff0c;提升数据质量已成…

【CT】LeetCode手撕—3. 无重复字符的最长子串

目录 题目1- 思路1-1 模式1&#xff1a;涉及去重判断1-2 模式2&#xff1a;遍历字符串区间 2- 题解⭐无重复字符的最长子串——题解思路 3- ACM实现 原题链接&#xff1a;3. 无重复字符的最长子串 题目 无重复字符的最长子串 给定一个字符串 s &#xff0c;请你找出其中不含有…

kubernetes负载均衡---MetalLB

https://github.com/metallb/metallb 参考 &#xff1a; https://mp.weixin.qq.com/s/MBOWfcTjFMmgJFWw-FIk0Q 自建的Kubernetes集群&#xff0c;默认情况下是不支持负载均衡的。当需要提供服务的外部访问时&#xff0c;可使用 Ingress、NodePort等方式。他们都存在一些问题 …

python基础篇(1):type()

1 type()函数 type()函数是Python内置的函数之一&#xff0c;它用于获取一个对象的数据类型。 一般语法如下&#xff1a; type(object) 其中&#xff0c;object是您要检查其类型的变量或对象。type()函数将返回一个表示对象类型的类型对象。 2 使用方式 &#xff08;1&…

C语言中指针的说明

什么是指针&#xff1f; 在C语言当中&#xff0c;我们可以将指针理解为内存当中存储的地址&#xff0c;就像生活当中&#xff0c;一个小区里面&#xff0c;在小区里面有很单元&#xff0c;每一栋单元&#xff0c;单元内的房间有着不同的房间号&#xff0c;我们可以同过几栋几单…

推荐系统学习 一

参考&#xff1a;一文看懂推荐系统&#xff1a;召回08&#xff1a;双塔模型——线上服务需要离线存物品向量、模型更新分为全量更新和增量更新_数据库全量更新和增量更新流程图-CSDN博客 一文看懂推荐系统&#xff1a;概要01&#xff1a;推荐系统的基本概念_王树森 小红书-CSD…

【Linux基础】安装nginx

【Linux基础】安装nginx 文章目录 【Linux基础】安装nginx1、下载nginx2、安装nginx3、使用nginx4、配置nginx环境变量 1、下载nginx 在Nginx的官网的下载页面中(http://nginx.org/en/download.html)&#xff0c;就展示了当前Nginx版本&#xff0c;并提供了下载的连接。 如下&a…

学习笔记——路由网络基础——静态路由(static)

三、静态路由(static) 1、静态路由 (1)定义 静态路由(Static)&#xff1a;由管理员手动配置和维护的路由。静态路由配置简单&#xff0c;被广泛应用于网络中。此外还可以实现负载均衡和路由备份。 静态路由默认优先级为60&#xff0c;如果想在多条静态路由中让某条路由优选…