flask小案例
""" 1、配置数据库 2、添加书和作者的模型 3、增加作者和书籍 4、使用模板显示数据库的查询 5、使用WTF显示表单 6、实现相关增删改查 """
分析下表的关系:

1、配置数据库
2、添加书和作者的模型
3、增加作者和书籍
from flask import Flask from flask_sqlalchemy import SQLAlchemy app=Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI']="mysql+pymysql://root:123456@localhost/flask_book" # 跟踪数据库,消耗性能,不建议开启,未来版本会移除 app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False db=SQLAlchemy(app) """ 1、配置数据库 2、添加书和作者的模型 3、增加作者和书籍 4、使用模板显示数据库的查询 5、使用WTF显示表单 6、实现相关增删改查 """ # 定义书和作者的模型 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') def __repr__(self): return 'Author %s'% self.name class Book(db.Model): __tablename__="books" id = db.Column(db.Integer,primary_key=True) name = db.Column(db.String(16),unique=True) author_id = db.Column(db.Integer,db.ForeignKey("authors.id")) def __repr__(self): return "Book %s %s %s" %(self.id,self.name,self.author_id)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <hr> <!--先遍历作者,然后在作者里遍历书籍--> <ul> {% for author in authors %} <li>{{ author.name }}</li> <ul> {% for book in author.books %} <li>{{ book.name }}</li> {% endfor %} </ul> {% endfor %} </ul> </body> </html>

使用WTF显示表单

# 自定义表单类 class AuthorFor(FlaskForm): author = StringField('作者', validators=[DataRequired()]) book = StringField('书籍', validators=[DataRequired()]) submit = SubmitField('提交') @app.route("/",methods=['GET','POST']) def index(): # 拿到所有作者的信息,信息传递给模板 authors = Author.query.all() # 创建表单类 form=AuthorFor() return render_template("index.html",authors=authors,form=form)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form method="post" action="/"> {{ form.csrf_token() }} {{ form.author.label }}{{ form.author }}<br> {{ form.book.label }}{{ form.book }}<br> {{ form.submit }} {#使用遍历获取闪现的消息#} {% for message in get_flashed_messages() %} {{ message }} {% endfor %} </form> </form> <hr> <!--先遍历作者,然后在作者里遍历书籍--> <ul> {% for author in authors %} <li>{{ author.name }}</li> <ul> {% for book in author.books %} <li>{{ book.name }}</li> {% endfor %} </ul> {% endfor %} </ul> </body> </html>

实现相关逻辑
from flask import Flask, render_template, request, flash from flask_sqlalchemy import SQLAlchemy from flask_wtf import FlaskForm from wtforms import StringField,SubmitField from wtforms.validators import DataRequired app=Flask(__name__) app.secret_key='tw1990' app.config['SQLALCHEMY_DATABASE_URI']="mysql+pymysql://root:123456@localhost/flask_book" # 跟踪数据库,消耗性能,不建议开启,未来版本会移除 app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False db=SQLAlchemy(app) """ 1、配置数据库 2、添加书和作者的模型 3、增加作者和书籍 4、使用模板显示数据库的查询 5、使用WTF显示表单 6、实现相关增删改查 """ # 定义书和作者的模型 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') def __repr__(self): return 'Author %s'% self.name class Book(db.Model): __tablename__="books" id = db.Column(db.Integer,primary_key=True) name = db.Column(db.String(16),unique=True) author_id = db.Column(db.Integer,db.ForeignKey("authors.id")) def __repr__(self): return "Book %s %s %s" %(self.id,self.name,self.author_id) # 自定义表单类 class AuthorFor(FlaskForm): author = StringField('作者', validators=[DataRequired()]) book = StringField('书籍', validators=[DataRequired()]) submit = SubmitField('提交') @app.route("/",methods=['GET','POST']) def index(): form = AuthorFor() """ 逻辑: 1、WTF函数验证 2、获取参数数据 3、书写逻辑 判断作者是否存在 判断存在,判断书籍是否存在,不存在就添加,如果重复,就提示错误,存在就添加 判断不存在,就添加作者和书籍 """ if request.method=="POST": if form.validate_on_submit(): # 去拿到请求参数 author_name = form.author.data book_name = form.book.data # 去数据库比较 author = Author.query.filter_by(name=author_name).first() if author: # 如果作者存在 # 判断书籍是否存在 book = Book.query.filter_by(name=book_name).first() if book: # 如果书籍存在 flash("已存在同名书籍") else: # 如果书籍不存在,就添加 # 数据库操作,可以用try,去捕获异常 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("参数有误") # 拿到所有作者的信息,信息传递给模板 authors = Author.query.all() # 创建表单类 return render_template("index.html",authors=authors,form=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)
删除逻辑:
redirect("www.baidu.com") 需要传入一个网址,这里重新写网址,很low
redirect(url_for('index')) 传入视图函数名,会返回视图函数对应的路由地址
book=Book.query.get(id)--->得到的是一个对象
<!--先遍历作者,然后在作者里遍历书籍--> <ul> {% for author in authors %} <li>{{ author.name }}</li> <ul> {% for book in author.books %} <li>{{ book.name }}<a href="{{ url_for('delete',id=book.id) }}">删除</a> </li> {% endfor %} </ul> {% endfor %} </ul>
@app.route('/delete/<int:id>') def delete(id): # 先查询这本书在不在 book = Book.query.get(id) if book: try: db.session.delete(book) db.session.commit() except Exception as e: print(e) flash("删除书籍出错") db.session.rollback() else: flash("该书籍不存在") return redirect(url_for('index'))

这里只需要更改下前端代码即可
<!--先遍历作者,然后在作者里遍历书籍--> <ul> {% for author in authors %} <li>{{ author.name }}</li> <ul> {% for book in author.books %} <li>{{ book.name }}<a href="{{ url_for('delete',id=book.id) }}">删除</a> </li> {% else %} <li>无</li> {% endfor %} </ul> {% endfor %} </ul>

删除作者
Book.query.filter_by(id=author.id).delete() 直接删
@app.route('/delete_author/<int:id>') def delete_author(id): # 先判断作者存不存在 author = Author.query.get(id) # 作者存在 if author: try: # 先删除书 Book.query.filter_by(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'))
<!--先遍历作者,然后在作者里遍历书籍--> <ul> {% for author in authors %} <li>{{ author.name }}<a href="{{ url_for('delete_author',id=author.id) }}">删除</a> </li> <ul> {% for book in author.books %} <li>{{ book.name }}<a href="{{ url_for('delete',id=book.id) }}">删除</a> </li> {% else %} <li>无</li> {% endfor %} </ul> {% endfor %} </ul>


浙公网安备 33010602011771号