我用Flask写了一个图书作者管理项目(附完整代码)

这次给大家带来的是一个非常小的Flask案例,刚好也与我们之前学习的Flask知识紧紧相结合。

首先看一下做出来的效果:

我们主要分为两部分来做,这两部分分别是上图的上部分的表单和下面的列表展示。

首先,我们需要通过flask_sqlalchemy来创建我们的数据表以及里面的数据:

from flask import Flask,render_template
from flask_sqlalchemy import SQLAlchemy
import pymysql
app = Flask(__name__)


class Config(object):
    # sqlalchemy的配置参数
    SQLALCHEMY_DATABASE_URI = "mysql+pymysql://root:数据库密码@127.0.0.1:3306/author_book?charset=utf8"

    # 设置sqlalchemy自动跟踪数据库
    SQLALCHEMY_TRACK_MODIFICATIONS = True

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)
    book = 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(32), unique=True)
    author_id = db.Column(db.Integer,db.ForeignKey("tbl_authors.id"))

if __name__ == '__main__':
    db.drop_all()
    db.create_all()
    author_kuls = Author(name="kuls")
    author_wu = Author(name="吴承恩")
    author_luo = Author(name="罗贯中")
    db.session.add_all([author_kuls,author_luo,author_wu])
    db.session.commit()

    book_pac = Book(name="爬虫从入门到入狱",author_id=author_kuls.id)
    book_wu = Book(name="西游记",author_id=author_wu.id)
    book_luo = Book(name="三国演义",author_id=author_luo.id)
    db.session.add_all([book_luo,book_pac,book_pac])
    db.session.commit()

通过上面代码,我们创建了两个数据表并在数据表中添加了相关的数据,这里的操作我就不详细说明,之前的文章中已经全部介绍过了。

第一步我们成功做完,成功的通过flask_sqlalchemy创建了数据表和数据的导入。

既然数据解决了,接下来就是来写前端相关的东西了。首先我们来写一下底下的列表部分

首先,编写视图函数,给前端提供数据:

@app.route("/")
def index():
    author_li = Author.query.all()
    return render_template("author_book.html", authors=author_li)

创建 author_book.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
   <ul>
       {% for author in authors %}
        <li>作者:{{author.name}}</li>
      <ul>
          {% for book in author.book %}
          <li>书籍:{{book.name}}</li>
          {% endfor %}

      </ul>
       {% endfor %}
   </ul>
</body>
</html>

最后效果图:

写完了上部分的内容,下面我们接着来写表单,表单在系列前面的文章中也写过,所以这里详细的不说,我们直接来使用:

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

@app.route("/",methods=["POST","GET"])
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)
        db.session.add(book)
        db.session.commit()


    author_li = Author.query.all()
    return render_template("author_book.html", authors=author_li,form = form)

我们创建一个表单模型类,并且在视图函数中进行表单数据的获取和储存。

 <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>

整体的视图函数逻辑很简单,首先获取到表单内容然后将其保存至数据库,最后执行查询数据库。通过这样每次我们点击提交按钮时会自动刷新列表里的内容。

接下来我们再为这个项目添加一个删除功能,整体的思路很简单,通过get请求拿到前端发送过来的book_id,后端再对这个book_id进行删除处理。

@app.route("/delete_book")
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"))

前端在书籍下面加一个a标签即可:

<!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.book %}
          <li>书籍:{{book.name}}</li>
          <a href="/delete_book?book_id={{book.id}}">删除</a>
          {% endfor %}

      </ul>
       {% endfor %}
   </ul>
</body>
</html>

整体的项目差不多就在这里结束了,当然你也可以自己去添加一些小功能。

完整代码:

author.py:

from flask import Flask,render_template,request,url_for,redirect
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的配置参数
    SQLALCHEMY_DATABASE_URI = "mysql+pymysql://root:liusHuang@123@127.0.0.1:3306/author_book?charset=utf8"
    SECRET_KEY = "fasnfjaksndddasd123"
    # 设置sqlalchemy自动跟踪数据库
    SQLALCHEMY_TRACK_MODIFICATIONS = True


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)
    book = 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(32), unique=True)
    author_id = db.Column(db.Integer,db.ForeignKey("tbl_authors.id"))


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

@app.route("/",methods=["POST","GET"])
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)
        db.session.add(book)
        db.session.commit()


    author_li = Author.query.all()
    return render_template("author_book.html", authors=author_li,form = form)


@app.route("/delete_book")
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()
    # author_kuls = Author(name="kuls")
    # author_wu = Author(name="吴承恩")
    # author_luo = Author(name="罗贯中")
    # db.session.add_all([author_kuls,author_luo,author_wu])
    # db.session.commit()
    #
    # book_pac = Book(name="爬虫从入门到入狱",author_id=author_kuls.id)
    # book_wu = Book(name="西游记",author_id=author_wu.id)
    # book_luo = Book(name="三国演义",author_id=author_luo.id)
    # db.session.add_all([book_luo,book_pac,book_pac])
    # db.session.commit()
    app.run(debug=True)

author_book.html:

<!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.book %}
          <li>书籍:{{book.name}}</li>
          <a href="/delete_book?book_id={{book.id}}">删除</a>
          {% endfor %}

      </ul>
       {% endfor %}
   </ul>
</body>
</html>

本文分享自微信公众号 - JAVAandPython君(JAVAandPythonJun)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-10-30

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏前端自习课

【CSS】378- [译]44个 CSS 精选知识点

一个周五的晚上,闲来无事整理下自己的 github(经常做收藏党),今天打算都过一遍,发现一个 star很高的项目,里面有大量的 CSS 片段,而且标题很诱人,...

10310
来自专栏咖啡拿铁

Java必备之从JDK到Dubbo的SPI深度剖析

本示例路径META-INF/services/com.springboot.dubbo.spi.SayHelloService

10220
来自专栏A周立SpringCloud

如何基于 Nacos 和 Sentinel ,实现灰度路由和流量防护一体化

基于 Nacos 和 Sentinel ,实现灰度路由和流量防护一体化的解决方案,发布在最新的 Nepxion Discovery 5.4.0 版本,具体参考:...

11120
来自专栏nginx遇上redis

HTTP/1.1 协议Expect: 100-continue

CURL transport error: transfer closed withoutstanding read data remaining

7130
来自专栏nginx遇上redis

Markdown也有xss

最近我测试一个web网站的时候发现,我可以通过markdown编辑器和渲染包来触发跨站点脚本(XSS)漏洞。这是我第一次遇到这种类型的漏洞,我发现它特别有趣,因...

8540
来自专栏铭毅天下

干货 | Elasticsearch 冷热集群架构实战

Elasticsearch实战数据量级少的时候,单节点就能玩的很6,但是随着数据量的增长,多节点分布式横向扩展集群是大势所趋。

46990
来自专栏阿dai_linux

将markdown文件转换成html格式

在写说明文档的时遇到一个问题:因为习惯了使用markdown写文档,在向nginx去发布的时候遇到一个语法格式不兼容的问题。

18520
来自专栏nginx遇上redis

nginx之rewrite详解2-企业级应用场景

(2)为了让搜索引擎搜录网站内容及用户体验更好,企业会将动态URL地址伪装成静态地址提供服务。

7550
来自专栏nginx遇上redis

正则表达式backreference

分析:模式<[hH][1-6]>匹配任何一级标题的开始标签,而且不区分大小写,在这个例子中它匹配到了<h1>、<h2>,</[hH][1-6]>匹配到了</h1...

8830
来自专栏APP自动化测试

iOS自动化探索(七)自动化测试框架pytest - 测试报告

JunitXML报告是一种很常用的测试报告,比如可以和Jenkins进行集成,在Jenkins的GUI上显示Pytest的运行结果,非常便利。 运行完case后...

6420

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励