【Flask】 python学习第一章 - 6.0 WTF表单 数据库 蓝图

时间:2023-03-08 17:33:46
【Flask】 python学习第一章 - 6.0 WTF表单 数据库 蓝图

WTF表单 

wtf.py

pip install flask-wtf  # 安装

from flask_wtf import FlaskForm 

from wtform import StringField, PasswordField, SubmmitField 

app.config["SECRET_KEY"] = ""
class register(flaskform):
  username = StringField("用户名:", render_kw={"placeholder":"占位符"})   password = PasswordField("密码:")   password2 = PassswordField("确认密码:")   submit = SubmitField("提交")
from flask import Flask, render_template
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField app = Flask(__name__) class register(FlaskForm):
username = StringField("用户名:", render_kw={'placeholder': "我是占位符"})
password = PasswordField("密码:")
password2 = PasswordField("确认密码")
submit = SubmitField("注册") @app.route("/",methods=["POST", "GET"])
def index():
registerform = register()
return render_template("demo4_template.html", form=registerform) if __name__ == '__main__':
app.run()

wtf.py

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{# <form method="post">#}
{# <label>用户名:</label><input type="text" name="username" placeholder="请输入用户名"><br/>#}
{# <label>密码:</label><input type="password" name="password" placeholder="请输入密码"><br/>#}
{# <label>确认密码:</label><input type="password" name="password2" placeholder="请输入确认密码"><br/>#}
{# <input type="submit" value="注册">#}
{##}
{#</form>#}
<br/>
<br/>
<br/>
<form method = "post">
{{ form.username.label }}{{ form.username }}<br/>
{{ form.password.label }}{{ form.password }}<br/>
{{ form.password2.label }}{{ form.password2 }}<br/>
{{ form.submit}} </form> </body>
</html>

demo4_teamplate.html

CSRF

  1. 在客户端向后端请求界面数据的时候,后端会往响应中的 cookie 中设置 csrf_token 的值
  2. 在 Form 表单中添加一个隐藏的的字段,值也是 csrf_token
  3. 在用户点击提交的时候,会带上这两个值向后台发起请求
  4. 后端接受到请求,以会以下几件事件:
    • 从 cookie中取出 csrf_token
    • 从 表单数据中取出来隐藏的 csrf_token 的值
    • 进行对比
  5. 如果比较之后两值一样,那么代表是正常的请求,如果没取到或者比较不一样,代表不是正常的请求,不执行下一步操作

Flask-SQLAlchemy

pip install flask-sqlalchemy flask-mysqldb  #安装

# 一对多 的关系定义

参考博客:https://www.cnblogs.com/liuwei0824/p/8290526.html

from flask import Flask
from flask_sqlalchemy import SQLAlchemy app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql://root:qqq123...A@127.0.0.1:3306/test27"
app.config['SQLALCHEMY_TRACK_MODIFICATION'] = False
# 初始化 sqlachemy
db = SQLAlchemy(app) # 定义SQL 模型 角色
class Role(db.Model):
# 指定表明 如不指明为类名小写
__tablename__ = "roles"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
# 唯一不重复 unique
name = db.Column(db.String(64), unique=True)
# 关联表 backref 给这行代码前面的user 添加一个属性 以便user可以通过user.role 可以访问Role的数据
users = db.relationship('User', backref='role') class User(db.Model):
# 指定表明 如不指明为类名小写
__tablename__ = "user"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
# 外键
role_id = db.Column(db.Integer, db.ForeignKey(Role.id)) def __repr__(self):
return 'user %d %s' % (self.id, self.name) # 用户 一个角色对应多个用户 @app.route('/')
def index():
return "index" if __name__ == '__main__':
# 创建所有表
db.drop_all()
db.create_all()
ro1 = Role(name="admin")
ro2 = Role(name="user")
db.session.add_all([ro1, ro2])
db.session.commit()
user1 = User(name="laowang", role_id=ro1.id)
user2 = User(name="laoli", role_id=ro2.id)
user3 = User(name="laoda", role_id=ro2.id) db.session.add_all([user1, user2, user3])
db.session.commit()
app.run(debug=True)
复制代码

一对多关系

# 数据库 查询 过滤 分页

from flask import Flask
from flask_sqlalchemy import SQLAlchemy app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql://root:qqq123...A@127.0.0.1:3306/test27"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# 初始化 sqlachemy
db = SQLAlchemy(app) # 定义SQL 模型 角色
class Role(db.Model):
# 定义表名
__tablename__ = 'roles'
# 定义列对象
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
us = db.relationship('User', backref='role') # repr()方法显示一个可读字符串
def __repr__(self):
return 'Role:%s' % self.name class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True, index=True)
email = db.Column(db.String(64), unique=True)
password = db.Column(db.String(64))
role_id = db.Column(db.Integer, db.ForeignKey('roles.id')) def __repr__(self):
return 'User:%s' % self.name # 用户 一个角色对应多个用户 @app.route('/')
def index():
return "index" def db_opt():
# 创建所有表
db.drop_all()
db.create_all()
# 再次插入一条数据
ro1 = Role(name='admin')
db.session.add(ro1)
db.session.commit()
# 再次插入一条数据
ro2 = Role(name='user')
db.session.add(ro2)
db.session.commit()
# 再次插入一条数据
us1 = User(name='wang', email='wang@163.com', password='', role_id=ro1.id)
us2 = User(name='zhang', email='zhang@189.com', password='', role_id=ro2.id)
us3 = User(name='chen', email='chen@126.com', password='', role_id=ro2.id)
us4 = User(name='zhou', email='zhou@163.com', password='', role_id=ro1.id)
us5 = User(name='tang', email='tang@itheima.com', password='', role_id=ro2.id)
us6 = User(name='wu', email='wu@gmail.com', password='', role_id=ro2.id)
us7 = User(name='qian', email='qian@gmail.com', password='', role_id=ro1.id)
us8 = User(name='liu', email='liu@itheima.com', password='', role_id=ro1.id)
us9 = User(name='li', email='li@163.com', password='', role_id=ro2.id)
us10 = User(name='sun', email='sun@163.com', password='', role_id=ro2.id)
db.session.add_all([us1, us2, us3, us4, us5, us6, us7, us8, us9, us10])
db.session.commit() def test():
# 查询所有用户数据
User.query.all()
# 查询有多少个用户
User.query.count()
# 查询第1个用户
User.query.first()
# 查询id为4的用户[3种方式]
User.query.get(4)
User.query.filter(User.id == 4).first()
User.query.filter_by(id=4).first()
# 查询名字结尾字符为g的所有数据[开始/包含]
User.query.filter(User.name.endswith('g')).all()
User.query.filter(User.name.contains("g")).all()
# 查询名字不等于wang的所有数据[2种方式]
User.query.filter(User.name != 'wang').all() # 查询名字和邮箱都以 li 开头的所有数据[2种方式]
from sqlalchemy import and_
User.query.filter(User.name.startswith("li"), User.email.startswith("li")).all()
User.query.filter(and_(User.name.startswith("li"), User.email.startswith("li"))).all()
# 查询password是 `123456` 或者 `email` 以 `itheima.com` 结尾的所有数据
from sqlalchemy import or_
User.query.filter(or_(User.password == "", User.email.endswith("itheima.com"))).all()
# 查询id为 [1, 3, 5, 7, 9] 的用户列表
User.query.filter(User.id.in_([1, 3, 5, 8, 9])).all()
# 查询name为liu的角色数据
User.query.filter(User.name == "liu").first().role
# 查询所有用户数据,并以邮箱排序
User.query.order_by(User.email).all()
# 正序
User.query.order_by(User.email.asc()).all()
# 倒叙
User.query.order_by(User.email.desc()).all()
# 每页3个,查询第2页的数据
paginate = User.query.paginate(2, 3)
# 列出
paginate.items
# 总页数
paginate.pages
# 当前页面
paginate.page if __name__ == '__main__':
db_opt()
app.run(debug=True)

sqlalchemy.py

# 导入数据 删除数据

from flask import Flask, render_template, flash, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm
from sqlalchemy import Column
from wtforms import StringField, SubmitField
from wtforms.validators import InputRequired app = Flask(__name__)
app.secret_key = "adueiowqjeo1" app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:qqq123...A@127.0.0.1:3306/booktest"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False db = SQLAlchemy(app) class AddFrom(FlaskForm):
author = StringField("作者", validators=[InputRequired('请输入作者名')])
book = StringField("书名", validators=[InputRequired("请输入书名")])
submit = SubmitField("提交") class Author(db.Model):
"""作者 一的一方"""
__tablename__ = "authors"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True) # 定义属性 以便作者模型可以通过直接通过该属性访问其多的一方的数据
# backref 给book添加了一个author属性 可以通过book.author 获取book对应的作者
books = db.relationship('Book', backref='author') class Book(db.Model):
"""书 多的一方"""
__tablename__ = "books"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
author_id: Column = db.Column(db.Integer, db.ForeignKey(Author.id)) @app.route("/delete_author/<author_id>")
def delete_author(author_id):
author = Author.query.get(author_id)
#Book.query.filter(Book.author_id==author_id).delete()
Author.query.filter(Author.id==author_id).delete()
db.session.delete(author)
db.session.commit() return redirect(url_for('index')) @app.route("/delete_book/<book_id>")
def delete_book(book_id): try:
book = Book.query.get(book_id)
except Exception as e:
print(e)
return "查询错误" if not book:
return "数据不存在" try:
db.session.delete(book)
db.session.commit()
except Exception as e:
print(e)
db.session.rollback()
return "删除失败" return redirect(url_for('index')) def createData():
# 生成数据
au1 = Author(name='老王')
au2 = Author(name='老尹')
au3 = Author(name='老刘')
# 把数据提交给用户会话
db.session.add_all([au1, au2, au3])
# 提交会话
db.session.commit()
bk1 = Book(name='老王回忆录', author_id=au1.id)
bk2 = Book(name='我读书少,你别骗我', author_id=au1.id)
bk3 = Book(name='如何才能让自己更骚', author_id=au2.id)
bk4 = Book(name='怎样征服美丽少女', author_id=au3.id)
bk5 = Book(name='如何征服英俊少男', author_id=au3.id)
# 把数据提交给用户会话
db.session.add_all([bk1, bk2, bk3, bk4, bk5])
# 提交会话
db.session.commit() @app.route("/", methods=["get", "post"])
def index():
"""返回首页"""
# 1.查询数据 form = AddFrom() # 2.将数据传入模板中进行渲染返回
# 查询作者指定名字
if form.validate_on_submit():
author_name = form.author.data
book_name = form.book.data sqlauthor = Author.query.filter(Author.name == author_name).first() if not sqlauthor:
try:
sqlauthor = Author(name=author_name)
db.session.add(sqlauthor)
db.session.commit() book = Book(name=book_name, author_id=sqlauthor.id)
db.session.add(book)
db.session.commit()
except Exception as e:
db.session.rollback()
print(e)
flash("添加失败")
else:
sqlbook = Book.query.filter(Book.name == book_name).first()
if not sqlbook:
try:
book = Book(name=book_name, author_id=sqlauthor.id)
db.session.add(book)
db.session.commit()
except Exception as e:
print(e)
flash("添加失败")
else:
flash("已存在")
else:
if request.method == "POST":
flash("输入有误") authors = Author.query.all()
return render_template("template1.html",
author=authors,
form=form
) if __name__ == '__main__':
db.drop_all()
db.create_all()
createData()
app.run(debug=True)

py

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板</title>
</head>
<body>
<h1>图书管理</h1>
<form method="post">
{{ form.csrf_token() }}
{{ form.author.label }}{{ form.author }}
{{ form.book.label }}{{ form.book }}
{{ form.submit }}
</form>
<ul>
{% for author in author %}
<li>{{ author.name }}<a href="/delete_author/{{ author.id }}"> 删除</a> </li>
<ul>
{% for book in author.books %}
<li>{{ book.name }}<a href="/delete_book/{{ book.id }}"> 删除</a></li>
{% endfor %}
</ul>
{% endfor %}
</ul> </body>
</html>

templates

# 多对多的关系

tags = db.Table('tags',
db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')),
db.Column('page_id', db.Integer, db.ForeignKey('page.id'))
) class Page(db.Model):
id = db.Column(db.Integer, primary_key=True)
tags = db.relationship('Tag', secondary=tags,
backref=db.backref('pages', lazy='dynamic')) class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True)

# blueprint  order.py

from flask  import blueprint

# 创建蓝图

order_blu = Blueprint("order_blue", __name__)

# 使用蓝图

@order_blue.route("/order")

def order():

  return "order_list"

# main.py

from order import order_blu

# 在APP上注册蓝图

app.register_blueprint(order_blu)

from flask import Blueprint

order_blu = Blueprint("blue", __name__)

@order_blu.route("/order")
def order():
return "order_list"

bluepoint_demo.py

from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
from Blueprint_demo import order_blu app = Flask(__name__)
app.register_blueprint(order_blu) @app.route("/")
def index():
return "hah" if __name__ == '__main__':
app.run(debug=True, port=2222)

main.py

__init__ 导包 初始化蓝图

views  注册路由

main.py 注册蓝图

一个爱学习的oscar