应用实例:Flask扩展Flask-WTF和Flask-SQLAlchemy

文件目录结构
./
├── main.py
├── templates
│ └── index.html
└── static
└── js
└── jquery-3.3.1.min.js

一共涉及三个文件
1、jquery-3.3.1.min.js 可百度下载
2、 main.py

# -*- coding: utf-8 -*-

from flask import Flask, render_template, request, url_for, redirect, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired

app = Flask(__name__)


# 配置数据库信息
class Config(object):
    SQLALCHEMY_DATABASE_URI = "mysql://root:123456@127.0.0.1:3306/demo"

    SQLALCHEMY_TRACK_MODIFICATIONS = True

    SECRET_KEY = "adsfasdf9932@@fdsafsdaf"


app.config.from_object(Config)

db = SQLAlchemy(app)


class Author(db.Model):
    """作者"""
    __tablename__ = "tbl_author"

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(32))
    books = db.relationship("Book", backref="author")


class Book(db.Model):
    """书籍"""
    __tablename__ = "tbl_book"

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64))
    author_id = db.Column(db.Integer, db.ForeignKey("tbl_author.id"))


def db_init():
    """
    初始化数据库
    mysql> create database demo default charset utf8;
    """
    db.drop_all()
    db.create_all()

    author1 = Author(name="吴承恩")
    author2 = Author(name="施耐庵")
    author3 = Author(name="罗贯中")
    author4 = Author(name="曹雪芹")
    db.session.add_all([author1, author2, author3, author4])
    db.session.commit()

    book1 = Book(name="西游记", author=author1)
    book2 = Book(name="红楼梦", author=author4)
    book3 = Book(name="三国演义", author=author3)
    book4 = Book(name="水浒传", author=author2)
    db.session.add_all([book1, book2, book3, book4])
    db.session.commit()

class AuthorBookForm(FlaskForm):
    """作者书籍表单"""
    author_name = StringField(label="作者姓名", validators=[DataRequired("作者姓名不能为空")])
    book_name = StringField(label="书籍名称", validators=[DataRequired("书籍名称不能为空")])
    submit = SubmitField(label="提交")

# 视图函数
@app.route("/", 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=author)
        db.session.add(book)
        db.session.commit()

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

@app.route("/deleteBook", methods=["POST"])
def delete_book():
    """删除书本数据
    接收json格式的数据 contentType: application/json
    """
    data = request.json
    book_id = data.get("bookId")

    book = Book.query.get(book_id)
    db.session.delete(book)
    db.session.commit()

    data = {
        "code": 0,
        "message": "delete success"
    }
    return jsonify(data)

@app.route("/deleteAuthor")
def delete_author():
    """删除作者书籍"""
    author_id = request.args.get("authorId")

    author = Author.query.get(author_id)
    db.session.delete(author)
    db.session.commit()

    return redirect(url_for("index"))

if __name__ == '__main__':
    # db_init()
    app.run(debug=True)

3、index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!-- 显示表单 -->
<form action="/" method="post">
    {{ form.csrf_token }}

    {{ form.author_name.label }}
    {{ form.author_name }}
    {% for msg in form.author_name.errors %}
        {{ msg }}
    {% endfor %}

    {{ form.book_name.label }}
    {{ form.book_name }}
    {% for msg in form.book_name.errors %}
        {{ msg }}
    {% endfor %}

    {{ form.submit }}

</form>

<hr/>

<!-- 显示作者书籍 -->
<ul>
    {% for author in authors %}
        <li>
            作者:{{ author.name }} <a href="/deleteAuthor?authorId={{ author.id }}">删除</a>
            <ul>
                {% for book in author.books %}
                    <li>书籍:{{ book.name }} <a href="javascript:" onclick="deleteBook({{ book.id }})">删除</a></li>
                {% endfor %}
            </ul>
        </li>
    {% endfor %}
</ul>

<script type="text/javascript" src="/static/js/jquery-3.3.1.min.js"></script>
<script>
    function deleteBook(bookId) {
        var data = {
            bookId: bookId
        };

        // 向后端发送json格式数据
        $.ajax({
            url: "/deleteBook", // 请求url
            type: "post", // 请求方式
            data: JSON.stringify(data), //向后端发送的请求体数据,将js对象转为json字符串
            contentType: "application/json",//向后端发送的数据格式
            dataType: "json", // 后端返回的数据格式
            success: function (result) {
                if (result.code === 0) {
                    location.href = "/";
                }
            }
        })
    }
</script>
</body>
</html>

显示效果


image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,400评论 1 45
  • 最近看了Flask Web开发:基于Python的Web应用开发实战,书中详细介绍了Web程序的开发、测试、部署过...
    SheHuan阅读 8,775评论 2 33
  • jHipster - 微服务搭建 CC_简书[https://www.jianshu.com/u/be0d56c4...
    quanjj阅读 794评论 0 2
  • Django是一个用 Python 编写的 Web 框架。Web 框架是一种软件,基于web框架可以开发动态网站,...
    guanalex阅读 7,162评论 0 5
  • 网络拓扑网络的连接和构成的形态成为网络拓扑
    Yix1a阅读 296评论 0 0