flask 实现增删改查

from flask import Flask,render_template, flash, request,url_for,redirect
# 导入数据库工具
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm

# 提交
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired,EqualTo

#编码
# import sys
# sys.setdefaultencoding("utf-8")

'''
1、配置数据库
a.导入SQLAlchemy扩展
b.创建db对象, 并设置参数
c.终端创建数据库

2、添加书和作者模型
a.模型继承 db.Model
b.__tablename__ :表明
c. db.Column :字段
3、添加数据
4、使用模板显示数据库查询的数据
a.查询所有的作者的信息,让信息传递给模板
b.模板中按照格式,依次for循环作者的书籍即可,(作者获取书籍, 用的是关系引用)
5、使用WTF显示表单
a.自定义表单类
b.模板中的显示
c.secret_key /编码 /csrf_token

6、实现相关的增删逻辑
a.增加数据
b.删除书籍 url_for的使用 、 for else的使用 、redirect(重定向)的使用
'''
app = Flask(__name__)


# 配置数据库的地址 数据库
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@localhost:3306/flask_books"

# 跟踪数据库的修改 -->不建议开启、 开启以后会性能会有影响、未来的版本会移除
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

#在flask项目中,Session, Cookies以及一些第三方扩展都会用到SECRET_KEY值,这是一个比较重要的配置值。
app.secret_key = "itheima"

#创建数据库对象
db = SQLAlchemy(app)

'''
这个网站解释了 flask框架封装数据库字段的解释 https://blog.csdn.net/appleyuchi/article/details/79372240

'''

class Book(db.Model):
# 表名字
__tablename__ = "books"

# 字段
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(16), unique=True)

# 外键 就是Book类中添加了一个author_id变量,数据类型db.Integer,第二个参数指定外键是哪个表中哪个(authors)的id。
author_id = db.Column(db.Integer,db.ForeignKey("authors.id"))

def __repr__(self):
return "Book: %s %s" % (self.name,self.author_id)


#定义书和作者模型
class Author(db.Model):
#表名字
__tablename__ = "authors"

#字段
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(16),unique=True)

#关系引用
books = db.relationship("Book",backref = "author")
'''
这句话比较复杂,仔细读下面的话:

0.添加到Author模型中的books属性代表这个关系的面向对象视角。对于一个Author类的实例,其books属性将返回与角色相关联的用户组成的列表。
1.db.Relationship()第一个参数表明这个关系的另一端是哪个模型(类)。如果模型类尚未定义,可使用字符串形式指定。
2.db.Relationship()第二个参数backref,将向Book类中添加一个author属性,从而定义反向关系。这一属性可替代author_id访问Author模型,此时获取的是模型对象,而不是外键的值。
'''

def __repr__(self):
return "Author: %s" % self.name

#自定义表单类
class AuthorForm(FlaskForm):
#validators=[DataRequired()] 验证函数
author = StringField("作者",validators=[DataRequired()])
book = StringField("书籍",validators=[DataRequired()])
submit = SubmitField("提交")


@app.route("/delete_author/<author_id>")
def delete_author(author_id):
#查询数据库,查看id的作者是否存在, 存在就删除
author = Author.query.get(author_id)

#如果作者存在
if author:
try:
#查询书籍查看是否存在, 并且删除
Book.query.filter_by(author_id = author.id).delete()

#删除作者
db.session.delete(author)

#删除以后提交
db.session.commit()

except Exception as e:
print(e)
flash("删除作者出错")
db.session.rollback()
else:
flash("作者找不到")

return redirect(url_for("index"))



@app.route("/delete_book/<book_id>")
def delete_book(book_id):
#查询数据库、是否有改id的书籍
book = Book.query.get(book_id)

#如果存在就删除、如果不存在就提示错误
if book:
try:
db.session.delete(book)
db.session.commit()

except Exception as e:
print(e)
flash("删除书籍错误")
db.session.rollback()
else:
flash("书籍找不到")

print(url_for("index"))

#删除以后重定向到index所对应的视图

return redirect(url_for("index"))




#验证就会出现GET/POST请求
@app.route('/',methods=["GET","POST"])
def index():

# 创建自定义的表单类
author_form = AuthorForm()
'''
6、 WTF可以一句话实现验证数据:

1、调用WTF的函数实现验证
2、验证通过获取数据
3、判断作者是否存在
4、判断书籍是否存在, 如果没有重复书籍就添加数据,如果重复就提示错误

5、如果作者不存在, 添加作者和书籍
6、验证不通过就提示错误
'''
#1、调用WTF的函数实现验证, 提交的时候验证 \ 验证是否有数据
if author_form.validate_on_submit():

#2、验证通过获取数据

#拿到作者input信息
author_name = author_form.author.data

#书籍input信心
book_name = author_form.book.data

#3、判断作者是否存在 (涉及到数据库查询操作、query.filter_by)
author = Author.query.filter_by(name = author_name).first()

#如果作者存在
if author:
#4、判断书籍是否存在, 如果没有重复书籍就添加数据,如果重复就提示错误
book = Book.query.filter_by( name = book_name).first()
if book:
flash("已经存在同名书籍")

else:
try:
#添加数据、 与数据库交互操作
new_book = Book(name = book_name,author_id = author.id)
db.session.add(new_book)
db.session.commit()

except Exception as e:
print(e)
flash("添加书籍失败")
#如果添加书籍失败就回滚一下
db.session.rollback()
else:
#如果作者不存在, 添加作者和书籍
try:
#添加作者
new_author = Author(name = author_name)
db.session.add(new_author)
db.session.commit()

new_book = Book(name = book_name,author_id = new_author.id)
db.session.add(new_book)
db.session.commit()
except Exception as e:
print(e)
flash("添加作者和书籍失败")
db.session.rollback()
else:
#flash("这个无论如何都会提示、因为没有做启动方式验证、启动方式是get或者post")

#6、如果是post请求, 才会提示有问题 验证不通过就提示错误 加上from flask import Flask,render_template, flash, request
if request.method == "POST":
flash("参数不全")
#查询所有的作者信息, 让信息传递给模板
authors = Author.query.all()
return render_template("books.html",authors=authors, form = author_form)



if __name__ == '__main__':
# 为了演示方便,先删除所有表,再创建
db.drop_all()

# 创建
db.create_all()

# 添加测试数据库
# 生成数据
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.run(debug = True)

猜你喜欢

转载自www.cnblogs.com/yuanjia8888/p/12162876.html