Web框架——Flask系列之综合案例——图书管理系统(十)

一、知识点:

  1. 表单创建
  2. 数据库操作
  3. 一对多关系演练

二、实现步骤:

  1. 创建数据库配置信息,定义模型类
  2. 创建数据库表,添加测试数据
  3. 编写html页面,展示数据
  4. 添加数据
  5. 删除书籍,删除作者

三、创建数据库连接信息,定义模型

在这里插入图片描述

from flask import Flask, render_template, redirect, url_for, flash, request
from flask_sqlalchemy import SQLAlchemy
from flask_wtf.csrf import CSRFProtect

app = Flask(__name__)

#开启csrf保护
CSRFProtect(app)

#设置数据库配置信息
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:123456@127.0.0.1:3306/library2"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False #压制警告信息

#创建SQLAlchemy对象,关联app
db = SQLAlchemy(app)

#设置密码
app.config['SECRET_KEY'] = "jfkdjfkdkjf"

#编写模型类
#作者(一方)
class Author(db.Model):
    __tablename__ = 'authors'
    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(64),unique=True)

    #关系属性和反向引用
    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 = db.Column(db.Integer,db.ForeignKey('authors.id')) #或者是, Author.id




#添加书籍
@app.route('/add_book', methods=['POST'])
def add_book():
    """
    思路分析:
    1.获取参数
    2.校验参数
    3.通过作者名称,查询作者对象
    4.判断作者,判断书籍,进行添加
    5.重定向展示页
    :return:
    """
    # 1.获取参数
    author_name = request.form.get("author")
    book_name = request.form.get("book")

    # 2.校验参数
    if not all([author_name,book_name]):
        return "作者或者书籍为空"

    # 3.通过作者名称,查询作者对象
    author = Author.query.filter(Author.name == author_name).first()  # 有金庸

    # 4.判断作者,判断书籍,进行添加
    # 判断作者是否存在
    if author:

        # 通过书籍名称,查询书籍对象 数据库,古龙写了 天龙八部
        book = Book.query.filter(Book.name == book_name, Book.author_id == author.id).first()

        # 判断书籍是否存在
        if book:
            flash('该作者有该书籍')
        else:
            # 创建书籍对象,添加到数据库
            book = Book(name=book_name, author_id=author.id)
            db.session.add(book)
            db.session.commit()

    else:
        # 创建作者添加到数据库
        author = Author(name=author_name)
        db.session.add(author)
        db.session.commit()

        # 创建书籍添加到数据库
        book = Book(name=book_name, author_id=author.id)
        db.session.add(book)
        db.session.commit()

    # 5.重定向展示页
    return redirect(url_for('show_page'))


#删除书籍
@app.route('/delete_book/<int:book_id>')
def delete_book(book_id):
    #1.根据编号获取书籍对象
    book = Book.query.get(book_id)

    #2.删除书籍
    db.session.delete(book)
    db.session.commit()

    #3.重定向页面展示
    return redirect(url_for('show_page'))

#删除作者
@app.route('/delete_author/<int:author_id>')
def delete_author(author_id):
    #1.通过编号获取作者对象
    author = Author.query.get(author_id)

    #2.删除作者书籍
    for book in author.books:
        db.session.delete(book)

    #3.删除作者对象
    db.session.delete(author)
    db.session.commit()

    #4.重定向展示页面
    return redirect(url_for('show_page'))


if __name__ == '__main__':

    app.run(debug=True)
  • myCode
from flask import Flask,render_template,flash,request
from flask_sqlalchemy import SQLAlchemy

from flask_wtf import FlaskForm
from wtforms import StringField,SubmitField
from wtforms.validators import DataRequired


app = Flask(__name__)

# 数据库配置:数据库地址、关闭自动跟踪修改
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:root@127.0.0.1/flask_books'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.secret_key = 'Zep03'

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


'''
1. 配置数据库
    a.导入SQLAlchemy扩展
    b.创建db对象,并配置参数
    c.通过mysql终端创建数据库
2. 添加书和作者的模型
    a.模型要继承db.Model
    b.__tablaname__:定义表名
    c.db.Column:定义字段名
    d.db.relationship: 关系引用
3. 添加数据
4. 使用模板显示数据库查询的数据
    a.查询所有的作者信息,将信息传递给模板
    b.模板中按照格式,一次for循环作者和书籍即可(作者获取书籍,用的是关系引用)
5. 使用WTF显示表单
    a.自定义表单类
    b.模板中显示
    c.设置secret_key/解决编码问题/csrf_token
6. 实现相关的增删逻辑
    a.增加数据
    
'''


# 定义书和作者模型

# 作者模型
class Author(db.Model):
    # 表名
    __tablename__ = 'authors'
    # 字段名
    id = db.Column(db.Integer,primary_key=True) #作者id
    name = db.Column(db.String(16),unique=True) #作者名name

    # 关系引用
    # books是给Author自己用的,author是给Book模型用的
    books = db.relationship('Book',backref='author')

    def __refr__(self):
        return 'Author: %s ' % self.name

# 书籍模型
class Book(db.Model):
    # 表名
    __tablename__ = 'books'

    # 字段名
    id = db.Column(db.Integer, primary_key=True)  # 书籍的id
    name = db.Column(db.String(16), unique=True)  # 书籍名name
    author_id = db.Column(db.Integer,db.ForeignKey('authors.id'))

    def __refr__(self):
        return 'Book: %s %s ' % self.name,self.author_id

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




@app.route('/',methods=['GET','POST'])
def index():
    # 创建自定义的表单类
    author_form = AuthorForm()

    '''
    验证逻辑:
    1. 调用WTF的函数实现验证
    2. 验证通过获取数据
    3. 判断作者是否存在
    4. 如果作者存在,判断书籍是否存在,没有重复书籍就添加书籍信息;如果重复就提示错误
    5. 如果作者不存在,添加作者和书籍
    6. 验证不通过就提示错误
    '''
    # 1. 调用WTF的函数实现验证
    if author_form.validate_on_submit():
        # 2. 验证通过获取数据
        author_name =  author_form.author.data
        book_name = author_form.book.data

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

        # 4. 如果作者存在,
        if author:
            # 判断书籍是否存在,
            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() # 添加失败要进行回滚操作!


        # 5. 如果作者不存在,添加作者和书籍
        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:

        # 6. 验证不通过就提示错误
        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)

在这里插入图片描述

四、创建表,添加测试数据

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)

五、数据显示&表单添加

  • 后端代码:
#展示页面
@app.route('/')
def show_page():

    #查询数据库
    authors = Author.query.all()

    # 渲染到页面
    return render_template('library.html',authors=authors)
  • 前端代码
  • 创建文件 library.html ,编写以下代码:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {#注册表单#}
    <form action="/add_book" method="post">

        {# 设置隐藏的csrf_token #}
        <input type="hidden" name="csrf_token" value="{{ csrf_token() }}">

        <p>
        <label>作者</label><input type="text" name="author"><br>
        </p>

        <p>
        <label>书籍</label><input type="text" name="book"><br>
        </p>

        <p>
        <input type="submit" value="添加">
        </p>

        {% for message in get_flashed_messages() %}
            <span style="color: red">{{ message }}</span>
        {% endfor %}

    </form>
    <hr>

    {# 书籍展示 #}
    <h2>书籍展示</h2>
    <ul>
        {% for author in authors %}
            <li>作者: {{ author.name }} <a href="{{ url_for('delete_author',author_id=author.id) }}">删除</a></li><br>
            <ul>
                {% for book in author.books %}
                    <li>书籍: {{ book.name }} <a href="{{ url_for('delete_book',book_id=book.id) }}">删除</a></li><br>
                {% endfor %}
            </ul>
        {% endfor %}
    </ul>
</body>
</html>

六、添加数据

  • 添加书籍
@app.route('/add_book', methods=['POST'])
def add_book():
  """
  思路分析:
  1.获取参数
  2.校验参数
  3.通过作者名称,查询作者对象
  4.判断作者,判断书籍,进行添加
  5.重定向展示页
  :return:
  """
  # 1.获取参数
  author_name = request.form.get("author")
  book_name = request.form.get("book")

  # 2.校验参数
  if not all([author_name,book_name]):
      return "作者或者书籍为空"

  # 3.通过作者名称,查询作者对象
  author = Author.query.filter(Author.name == author_name).first()  # 有金庸

  # 4.判断作者,判断书籍,进行添加
  # 判断作者是否存在
  if author:

      # 通过书籍名称,查询书籍对象 数据库,古龙写了 天龙八部
      book = Book.query.filter(Book.name == book_name, Book.author_id == author.id).first()

      # 判断书籍是否存在
      if book:
          flash('该作者有该书籍')
      else:
          # 创建书籍对象,添加到数据库
          book = Book(name=book_name, author_id=author.id)
          db.session.add(book)
          db.session.commit()

  else:
      # 创建作者添加到数据库
      author = Author(name=author_name)
      db.session.add(author)
      db.session.commit()

      # 创建书籍添加到数据库
      book = Book(name=book_name, author_id=author.id)
      db.session.add(book)
      db.session.commit()

  # 5.重定向展示页
  return redirect(url_for('show_page'))

七、删除数据

  • 删除书籍
#删除书籍
@app.route('/delete_book/<int:book_id>')
def delete_book(book_id):
    #1.根据编号获取书籍对象
    book = Book.query.get(book_id)

    #2.删除书籍
    db.session.delete(book)
    db.session.commit()

    #3.重定向页面展示
    return redirect(url_for('show_page'))
  • 删除作者
#删除作者
@app.route('/delete_author/<int:author_id>')
def delete_author(author_id):
    #1.通过编号获取作者对象
    author = Author.query.get(author_id)

    #2.删除作者书籍
    for book in author.books:
        db.session.delete(book)

    #3.删除作者对象
    db.session.delete(author)
    db.session.commit()

    #4.重定向展示页面
    return redirect(url_for('show_page'))

八、案例完整代码

在这里插入图片描述
在这里插入图片描述

  • Flask_books_project.py文件
from flask import Flask,render_template,flash,request,redirect,url_for
from flask_sqlalchemy import SQLAlchemy

from flask_wtf import FlaskForm
from wtforms import StringField,SubmitField
from wtforms.validators import DataRequired


app = Flask(__name__)

# 数据库配置:数据库地址、关闭自动跟踪修改
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:root@127.0.0.1/flask_books'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.secret_key = 'Zep03'

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


'''
1. 配置数据库
    a.导入SQLAlchemy扩展
    b.创建db对象,并配置参数
    c.通过mysql终端创建数据库
2. 添加书和作者的模型
    a.模型要继承db.Model
    b.__tablaname__:定义表名
    c.db.Column:定义字段名
    d.db.relationship: 关系引用
3. 添加数据
4. 使用模板显示数据库查询的数据
    a.查询所有的作者信息,将信息传递给模板
    b.模板中按照格式,一次for循环作者和书籍即可(作者获取书籍,用的是关系引用)
5. 使用WTF显示表单
    a.自定义表单类
    b.模板中显示
    c.设置secret_key/解决编码问题/csrf_token
6. 实现相关的增删逻辑
    a.增加数据
    b.删除书籍——》网页中删除——》点击需要发送书籍的ID给删除书籍的路由——》路由需要接收参数
    url_for的使用 / for else的使用 / redirect的使用
    c.删除作者
    
'''


# 定义书和作者模型

# 作者模型
class Author(db.Model):
    # 表名
    __tablename__ = 'authors'
    # 字段名
    id = db.Column(db.Integer,primary_key=True) #作者id
    name = db.Column(db.String(16),unique=True) #作者名name

    # 关系引用
    # books是给Author自己用的,author是给Book模型用的
    books = db.relationship('Book',backref='author')

    def __refr__(self):
        return 'Author: %s ' % self.name

# 书籍模型
class Book(db.Model):
    # 表名
    __tablename__ = 'books'

    # 字段名
    id = db.Column(db.Integer, primary_key=True)  # 书籍的id
    name = db.Column(db.String(16), unique=True)  # 书籍名name
    author_id = db.Column(db.Integer,db.ForeignKey('authors.id'))

    def __refr__(self):
        return 'Book: %s %s ' % self.name,self.author_id

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

@app.route('/delete_author/<author_id>')
def delete_author(author_id):
    # 查询数据库,是否有该ID的作者,如果有就删除(先删书,再删作者),没有就提示错误
    # 1.查询数据库,
    author = Author.query.get(author_id)
    # 2.如果有就删除(先删书,再删作者)
    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()
            # 3.没有就提示错误
    else:
        flash('作者找不到~')
    return redirect(url_for('index'))



@app.route('/delete_book/<book_id>')
def delete_book(book_id):
    # 1. 查询数据库,是否有该ID的书,
    book = Book.query.get(book_id)
    # 2.如果有就删除,
    if book:
        try:
            db.session.delete(book)
            db.session.commit()
        except Exception as e:
            print(e)
            flash('删除书籍出错!!!')
            db.session.rollback()
    # 3.没有就提示错误
    else:
        flash('书籍找不到~')



    # 如何返回当前网址——》重定向
    # return redirect('www.baidu.com')
    # redirect():重定向,需要传入网址/路由地址
    # url_for():需要传入视图函数名,返回该视图函数对应的路由地址
    print(url_for('index'))
    return redirect(url_for('index'))





@app.route('/',methods=['GET','POST'])
def index():
    # 创建自定义的表单类
    author_form = AuthorForm()

    '''
    验证逻辑:
    1. 调用WTF的函数实现验证
    2. 验证通过获取数据
    3. 判断作者是否存在
    4. 如果作者存在,判断书籍是否存在,没有重复书籍就添加书籍信息;如果重复就提示错误
    5. 如果作者不存在,添加作者和书籍
    6. 验证不通过就提示错误
    '''
    # 1. 调用WTF的函数实现验证
    if author_form.validate_on_submit():
        # 2. 验证通过获取数据
        author_name =  author_form.author.data
        book_name = author_form.book.data

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

        # 4. 如果作者存在,
        if author:
            # 判断书籍是否存在,
            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() # 添加失败要进行回滚操作!


        # 5. 如果作者不存在,添加作者和书籍
        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:

        # 6. 验证不通过就提示错误
        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)
  • books.html文件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>图书管理</title>
</head>
<body>
    <form method="post">
        {{ form.csrf_token() }}
        {{ form.author.label }} {{ form.author }} <br>
        {{ form.book.label }} {{ form.book }} <br>
        {{ form.submit }} <br>
    </form>

<!--    显示消息闪现的内容-->
    {% for message in get_flashed_messages() %}
        {{message}}
    {% endfor %}

    <hr>

<!--    先遍历作者,然后在作者里遍历书籍-->
    <ul>
        {% for author in authors %}
        <li>{{author.name}} <a href="{{url_for('delete_author', author_id = author.id)}}">删除</a></li>

        <ul>
            {% for book in author.books %}
                <li>{{book.name}} <a href="{{url_for('delete_book', book_id = book.id)}}">删除</a></li>
            {% else %}
                <li></li>
            {% endfor %}
        </ul>
        {% endfor %}
    </ul>

</body>
</html>

第一种 删除书籍的实现方法(通过post请求来实现)

  • myCode
from flask import Flask,render_template,request,redirect,url_for,jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm
from wtforms import StringField,SubmitField
from wtforms.validators import DataRequired
import json
app = Flask(__name__)


class Config(object):
    '''配置参数'''
    # 数据库sqlAlchemy的配置参数,数据库链接地址
    SQLALCHEMY_DATABASE_URI = "mysql://root:root@127.0.0.1:3306/author_book_py04"

    # 动态追踪修改设置,如未设置只会提示警告
    SQLALCHEMY_TRACK_MODIFICATIONS = True

    SECRET_KEY = "JDIOGDKFNKXNCV12345D4FSDFS"


app.config.from_object(Config)

db = SQLAlchemy(app)

# 定义数据库的模型
class Author(db.Model):
    '''作者表'''
    __tablename__ = "tbl_authors"

    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(32),unique=True)

    books = db.relationship("Book",backref = "author")


class Book(db.Model):
    '''作者表'''
    __tablename__ = "tbl_books"

    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(64),unique=True)

    author_id = db.Column(db.Integer,db.ForeignKey('tbl_authors.id'))


# 创建表单模型类
class AuthorBookForm(FlaskForm):
    '''作者书籍表单模型类'''
    author_name = StringField(label="作者:",validators=[DataRequired("作者必填!")])
    book_name = StringField(label="书名:",validators=[DataRequired("书名必填!")])
    submit = SubmitField(label="保存")

@app.route("/index",methods=["GET","POST"])
def index():
    # 创建表单对象
    form = AuthorBookForm()

    # 验证表单成功
    if form.validate_on_submit():
        author_name = form.author_name.data
        book_name = form.book_name.data

        # 保存到数据库
        author = Author(name=author_name)
        db.session.add(author)
        db.session.commit()

        book = Book(name=book_name,author_id=author.id)
        # book = Book(name=book_name,author=author)
        db.session.add(book)
        db.session.commit()

    # 查询数据库
    author_li = Author.query.all()
    return render_template("author_book.html",authors = author_li,form=form)


# 约定前端传过来的数据格式:
# post  /delete_book  json
# {"book_id":xxx}

# 删除书籍
@app.route("/delete_book",methods=["POST"])
def delete_book():
    # 提取参数
    # 如果前端发送的请求体数据是json格式,
    # get_json会解析成字典格式
    # 前提:要求前端传送的数据的
    # Content-Type:application/json
    req_dict = request.get_json()
    # 将json格式字符串转换为python中的字典
    # json.loads(req_data)

    book_id = req_dict.get("book_id")

    # 删除数据
    book = Book.query.get(book_id)
    db.session.delete(book)
    db.session.commit()

    # "Content-Typel":"application/json"
    return jsonify(code=0,message="OK")



if __name__ == '__main__':
    db.drop_all()
    db.create_all()
    # 生成数据
    au_xi = Author(name='我吃西红柿')
    au_qian = Author(name='萧潜')
    au_san = Author(name='唐家三少')
    db.session.add_all([au_xi,au_qian,au_san])
    db.session.commit()


    bk_xi = Book(name='吞噬星空',author_id=au_xi.id)
    bk_xi2 = Book(name='寸芒',author_id=au_qian.id)
    bk_qian = Book(name='飘渺之旅',author_id=au_qian.id)
    bk_san = Book(name='冰火魔厨',author_id=au_san.id)
    db.session.add_all([bk_xi,bk_xi2,bk_qian,bk_san])
    db.session.commit()
    app.run(debug=True)


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <form method="post">
        {{form.csrf_token}}

        {{form.author_name.label}}
        <p>{{form.author_name}}</p>
        {% for msg in form.author_name.errors %}
            <p>{{msg}}</p>
        {% endfor %}

        {{form.book_name.label}}
        <p>{{form.book_name}}</p>
        {% for msg in form.book_name.errors %}
            <p>{{msg}}</p>
        {% endfor %}

        {{form.submit}}



    </form>
    <hr>
    <ul>
        {% for author in authors %}
        <li>作者:{{author.name}}</li>
        <ul>
            {% for book in author.books %}
            <li>书籍:{{book.name}}</li>
            <a href="javascript:;"  book-id="{{book.id}}">删除</a>
            {% endfor %}
        </ul>

        {% endfor %}
    </ul>
    <script src="../static/js/jquery-3.5.0.js"></script>
    <script>

        $("a").click(function () {
            var data = {
                book_id:$(this).attr("book-id")
            };
            // # 将上面data字典格式的数据转换为json字符串格式
            var req_json = JSON.stringify(data)

            // $.post("/delete_book",req_json,function (resp) {
            //     if (resp.code ==0) {
            //         location.href = "/index";
            //     }
            // },"json")
            $.ajax({
                url:"/delete_book", //请求的后端url
                type:"post", //请求方式
                data:req_json, // 向后端发送的请求体数据
                contentType:"application/json", //指明向后端发送的数据格式
                dataType:"json", // 指明后端返回的数据格式为json
                success:function (resp) {
                    if (resp.code == 0) {
                        alert("ok")
                        location.href = "/index";
                    }
                }
            })
        })
    </script>
</body>
</html>

在这里插入图片描述
重点解读:
在这里插入图片描述

第二种 删除书籍的实现方法(通过get请求来实现)

  • myCode
from flask import Flask,render_template,request,redirect,url_for,jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm
from wtforms import StringField,SubmitField
from wtforms.validators import DataRequired
import json
app = Flask(__name__)


class Config(object):
    '''配置参数'''
    # 数据库sqlAlchemy的配置参数,数据库链接地址
    SQLALCHEMY_DATABASE_URI = "mysql://root:root@127.0.0.1:3306/author_book_py04"

    # 动态追踪修改设置,如未设置只会提示警告
    SQLALCHEMY_TRACK_MODIFICATIONS = True

    SECRET_KEY = "JDIOGDKFNKXNCV12345D4FSDFS"


app.config.from_object(Config)

db = SQLAlchemy(app)

# 定义数据库的模型
class Author(db.Model):
    '''作者表'''
    __tablename__ = "tbl_authors"

    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(32),unique=True)

    books = db.relationship("Book",backref = "author")


class Book(db.Model):
    '''作者表'''
    __tablename__ = "tbl_books"

    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(64),unique=True)

    author_id = db.Column(db.Integer,db.ForeignKey('tbl_authors.id'))


# 创建表单模型类
class AuthorBookForm(FlaskForm):
    '''作者书籍表单模型类'''
    author_name = StringField(label="作者:",validators=[DataRequired("作者必填!")])
    book_name = StringField(label="书名:",validators=[DataRequired("书名必填!")])
    submit = SubmitField(label="保存")

@app.route("/index",methods=["GET","POST"])
def index():
    # 创建表单对象
    form = AuthorBookForm()

    # 验证表单成功
    if form.validate_on_submit():
        author_name = form.author_name.data
        book_name = form.book_name.data

        # 保存到数据库
        author = Author(name=author_name)
        db.session.add(author)
        db.session.commit()

        book = Book(name=book_name,author_id=author.id)
        # book = Book(name=book_name,author=author)
        db.session.add(book)
        db.session.commit()

    # 查询数据库
    author_li = Author.query.all()
    return render_template("author_book.html",authors = author_li,form=form)


# 约定前端传过来的数据格式:
# post  /delete_book  json
# {"book_id":xxx}

# # 删除书籍
# @app.route("/delete_book",methods=["POST"])
# def delete_book():
#     # 提取参数
#     # 如果前端发送的请求体数据是json格式,
#     # get_json会解析成字典格式
#     # 前提:要求前端传送的数据的
#     # Content-Type:application/json
#     req_dict = request.get_json()
#     # 将json格式字符串转换为python中的字典
#     # json.loads(req_data)
#
#     book_id = req_dict.get("book_id")
#
#     # 删除数据
#     book = Book.query.get(book_id)
#     db.session.delete(book)
#     db.session.commit()
#
#     # "Content-Typel":"application/json"
#     return jsonify(code=0,message="OK")
#



# 删除书籍
@app.route("/delete_book",methods=["GET"])
def delete_book():
    book_id = request.args.get("book_id")

    # 删除数据
    book = Book.query.get(book_id)
    db.session.delete(book)
    db.session.commit()


    return redirect(url_for("index"))



if __name__ == '__main__':
    db.drop_all()
    db.create_all()
    # 生成数据
    au_xi = Author(name='我吃西红柿')
    au_qian = Author(name='萧潜')
    au_san = Author(name='唐家三少')
    db.session.add_all([au_xi,au_qian,au_san])
    db.session.commit()


    bk_xi = Book(name='吞噬星空',author_id=au_xi.id)
    bk_xi2 = Book(name='寸芒',author_id=au_qian.id)
    bk_qian = Book(name='飘渺之旅',author_id=au_qian.id)
    bk_san = Book(name='冰火魔厨',author_id=au_san.id)
    db.session.add_all([bk_xi,bk_xi2,bk_qian,bk_san])
    db.session.commit()
    app.run(debug=True)


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <form method="post">
        {{form.csrf_token}}

        {{form.author_name.label}}
        <p>{{form.author_name}}</p>
        {% for msg in form.author_name.errors %}
            <p>{{msg}}</p>
        {% endfor %}

        {{form.book_name.label}}
        <p>{{form.book_name}}</p>
        {% for msg in form.book_name.errors %}
            <p>{{msg}}</p>
        {% endfor %}

        {{form.submit}}
    </form>
    <hr>
    <ul>
        {% for author in authors %}
        <li>作者:{{author.name}}</li>
        <ul>
            {% for book in author.books %}
            <li>书籍:{{book.name}}</li>
<!--            <a href="javascript:;"  book-id="{{book.id}}">删除</a>-->
            <a href="/delete_book?book_id={{book.id}}" >GET删除</a>
            {% endfor %}
        </ul>

        {% endfor %}
    </ul>
    <script src="../static/js/jquery-3.5.0.js"></script>
    <script>

        // $("a").click(function () {
        //     var data = {
        //         book_id:$(this).attr("book-id")
        //     };
        //     // # 将上面data字典格式的数据转换为json字符串格式
        //     var req_json = JSON.stringify(data)
        //
        //     // $.post("/delete_book",req_json,function (resp) {
        //     //     if (resp.code ==0) {
        //     //         location.href = "/index";
        //     //     }
        //     // },"json")
        //     $.ajax({
        //         url:"/delete_book", //请求的后端url
        //         type:"post", //请求方式
        //         data:req_json, // 向后端发送的请求体数据
        //         contentType:"application/json", //指明向后端发送的数据格式
        //         dataType:"json", // 指明后端返回的数据格式为json
        //         success:function (resp) {
        //             if (resp.code == 0) {
        //                 alert("ok")
        //                 location.href = "/index";
        //             }
        //         }
        //     })
        // })
    </script>
</body>
</html>

重点解读:
在这里插入图片描述

  • 12
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值