数据库课程设计图书管理系统(Python-Flask框架之图书管理系统项目 , 附详解源代码及效果图)

Posted

篇首语:没有知识就不可能对生活作出正确的解释。本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库课程设计图书管理系统(Python-Flask框架之图书管理系统项目 , 附详解源代码及效果图)相关的知识,希望对你有一定的参考价值。

数据库课程设计图书管理系统(Python-Flask框架之图书管理系统项目 , 附详解源代码及效果图)



该图书管理系统要实现的功能如下

1. 可以通过添加窗口添加书籍或作者, 如果要添加的作者和书籍已存在于书架上, 则给出相应的提示.

2. 如果要添加的作者存在, 而要添加的书籍书架上没有, 则将该书籍添加到该作者栏.

3. 如果要添加的作者和书籍都不存在于书架上 , 则将书籍和作者一起添加.

4. 每个书籍和作者旁边都有一个删除按钮 , 点击删除书籍的按钮可以将该书籍删除 , 若某作者栏的书籍全部删除完毕则显示"无".

5. 若直接点击删除作者按钮, 则会将该作者和其书籍一起全部删除掉.

该系统的实现工具: Python的Flask框架以及MySQL数据库.

效果图如下

图1

图2

图3

Python源代码如下

# coding=utf-8from flask import Flask,render_template,request,flash,redirect,url_forfrom flask_sqlalchemy import SQLAlchemyfrom flask_wtf import FlaskFormfrom wtforms import StringField,SubmitFieldfrom wtforms.validators import DataRequiredapp = Flask(__name__)"""1. 配置数据库    a.导入SQLALchemy扩展    b.创建db对象, 并配置参数    c.终端创建数据库2. 添加作者和书模型(类)    a.模型继承自db.Model    b.__tablename__:表名    c. db.Column:字段    d. db.relationship:关系引用3. 添加数据4. 使用模板显示数据库查询到的数据    a.查询所有的作者信息, 让信息传递给模板    b.模板中按照格式, 依次for循环作者和书籍即可(通过作者获取书籍, 用的是关系引用)5. 使用WTF显示表单     a.自定义表单类    b.模板中显示    c.设置secret_key6. 实现相关的增删逻辑    a.添加作者/书籍    b.删除书籍: redirect(重定向)/url_for(指向路由)/for else  的使用.    c.删除作者(要先删除该作者的书籍, 再删除该作者)"""# 配置数据库的地址URI , 格式 "数据库类型+数据库驱动名称://用户名:密码@机器地址:端口号/数据库名"  , 端口号可以不写.# python3中用的mysql驱动是mysql-connector , 已经不支持python2的MySQLdb驱动.app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+mysqlconnector://root:password@127.0.0.1/books_demo"# 跟踪数据库的修改 --> 不建议开启 , 一是消耗性能 , 二是未来的版本中会移除.app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = Falseapp.secret_key = "hwhefsewljfejrlesjfl"      # 没设置secret_key会有报错提醒# 将app作为参数传入这个关联工具 , 创建一个两者相关联对象dbdb = SQLAlchemy(app)# 注意: web框架里面的模型类基本都是要继承自导入的模块中的某个父类 , 这样才会起到关联的作用.class Author(db.Model):    """创建作者子类"""    __tablename__ = "authors"           # 定义表名    # 定义字段    # db.Column表示是一个字段 , db.Integer就代表id这个字段的数据类型是整数 , primary_key代表主键(主关键字) , 是作为表的行的唯一标识.    # db.String代表是字符串类型 , 字符串长度定义个n个字节 , unique(唯一的) , unique=True代表这列不允许出现重复的值.    id = db.Column(db.Integer,primary_key=True)    name = db.Column(db.String(64),unique=True)        # string的长度随便写个2的倍数就行了    # 在"一对多"的一中定义author_book属性 , 该属性不会出现在字段中 , 后面的backref="author"是给Book反向引用的    # 由于是"一对多" , 所以"多"的地方用Book参数 , "一"的地方用不加s的实例对象参数author.    author_book = db.relationship("Book",backref="author")    def __repr__(self):        """返回定制消息, 与__str__作用类似"""        return "Author: %d %s"%(self.id,self.name)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"))      # 表名.id 来建立外键关联    def __repr__(self):        return "Book: %d %s"%(self.id,self.name)class TrueForm(FlaskForm):    """表单扩展常用的模型(类)有三种: StringField, PasswordField,  SubmitField , 这里只用到两种        然后传入参数并创建出各自的实例对象 , 以供其它地方使用.    """    author = StringField("作者",validators=[DataRequired()])    book = StringField("书籍",validators=[DataRequired()])    submit = SubmitField("添加")def make_author_book():    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_id=author1.id)    book2 = Book(name="<<天龙八部>>", author_id=author1.id)    book3 = Book(name="<<鹿鼎记>>", author_id=author1.id)    book4 = Book(name="<<笑傲江湖>>", author_id=author1.id)    book5 = Book(name="<<武林外史>>", author_id=author2.id)    book6 = Book(name="<<萧十一郎>>", author_id=author2.id)    book7 = Book(name="<<小李飞刀>>", author_id=author2.id)    book8 = Book(name="<<狂人日记>>", author_id=author3.id)    book9 = Book(name="<<阿Q正传>>", author_id=author3.id)    book10 = Book(name="<<家>>", author_id=author4.id)    book11 = Book(name="<<春>>", author_id=author4.id)    book12 = Book(name="<<秋>>", author_id=author4.id)    db.session.add_all([book1,book2,book3,book4,book5,book6,                        book7,book8,book9,book10,book11,book12])    db.session.commit()@app.route("/",methods=["GET","POST"])def add_author_book():    true_form = TrueForm()    """    1.调用WTF的函数实现验证    2.验证通过则获取数据        3.判断作者是否存在        4.如果作者存在, 则判断书籍是否存在, 没有重复的书籍就添加数据, 如果重复就提示错误.        5.如果作者不存在, 就添加作者和书籍    6.验证不通过就提示错误.    """    # 调用WTF的函数实现验证    if true_form.validate_on_submit():        # 2.验证通过则获取此时填入的数据        author_name = true_form.author.data        book_name = true_form.book.data        # 3.判断作者是否存在, Author.query.filter_by(name=author_name)是查询, .first()才是拿到数据.        author_query = Author.query.filter_by(name=author_name).first()        # 4.如果作者存在        if author_query:            book_query = Book.query.filter_by(name=book_name).first()       # 查询并拿数据            if book_query:                flash("您要添加的书籍已存在!")            else:                try:                    new_book = Book(name="<<%s>>"%book_name,author_id=author_query.id)                    db.session.add(new_book)                    db.session.commit()                except Exception as e:                    flash("添加书籍错误!")                    db.session.rollback()      # 回滚操作        else:            # 5.如果作者不存在            try:                new_author = Author(name=author_name)                db.session.add(new_author)                db.session.commit()                new_book = Book(name="<<%s>>"%book_name, author_id=new_author.id)                db.session.add(new_book)                db.session.commit()            except Exception as e:                flash("添加作者和书籍错误!")                db.session.rollback()    else:        # 验证不通过        if request.method == "POST":            flash("参数错误!")    # 查询所有的作者信息, 让信息传递给模板    all_authors = Author.query.all()    return render_template("book_manage.html",all_authors=all_authors,form=true_form)# 网页中删除书籍-->将book_id参数传到路由, 路由再将book_id传入delete_book函数内部使用.# < >尖括号代表路由参数, 路由需要接受参数@app.route("/delete_book/<book_id>",methods=["GET","POST"])def delete_book(book_id):    # 1.查询书籍并拿数据    book = Book.query.get(book_id)    try:        db.session.delete(book)        db.session.commit()    except Exception as e:        flash("删除错误!")        db.session.rollback()    # redirect重定向回到根路径, redirect接收路由地址参数, 或者直接接收网址参数(http://xxxxx.com)    # url_for("index"): 需要传入视图函数名, 返回该视图函数对应的路由地址(url)    return redirect(url_for("add_author_book"))# 删除作者@app.route("/delete_author/<author_id>",methods=["GET","POST"])def delete_author(author_id):    # 1.查询作者并拿数据    author = Author.query.get(author_id)    try:        # 查询书籍并删除, 直接在查询后面跟 .delete()就可以直接将查询到的结果删除掉        Book.query.filter_by(author_id=author.id).delete()        db.session.delete(author)        db.session.commit()    except Exception as e:        flash("删除错误!")        db.session.rollback()        # 回滚    return redirect(url_for("add_author_book"))       # 重定向回到根路径if __name__ == '__main__':    # 先删除所有表, 在创建表之前要先删掉表    db.drop_all()    # 再创建所有表    db.create_all()    make_author_book()    app.run(debug=True)

HTML源代码如下

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>图书管理系统 | by-myself</title></head><body>从此处添加书籍: <br><br><form method="post">     form.csrf_token()                                form.author.label form.author<br>                               form.book.label form.book<br>                                                   form.submit<br>    <br>    # 显示消息闪现的内容 #    % for message in get_flashed_messages() %                                            message    %endfor%</form><br><hr><h1>                   书籍目录</h1><ul>    <ul>        <ul>            % for author in all_authors %                <li>author.name   <a href="url_for("delete_author",author_id=author.id)">删除</a></li>                <ul>                    % for book in author.author_book %                        <li>book.name   <a href=" url_for("delete_book",book_id=book.id) ">删除</a></li>                    % else %                        <li>无</li>                    % endfor %                </ul>            % endfor %        </ul>    </ul></ul></body></html>

小结

该实战项目短小精悍, 麻雀虽小但五脏俱全, 虽没有精美的前端画面和复杂的页面功能, 但涵盖了基本的前后端交互, 以及动态的数据处理过程, 比较适合新手作为入门的练手项目。


声明: 该篇文章系本人原创作品, 欢迎点赞、转发和评论, 禁止转载, 谢谢配合!

相关参考

大数据专业学什么课程

...专业知识、有数据思维)。3、以中国人民大学为例:基础课程:数学分析、高等代数、普通物理数学与信息科学概论、数据结构、数据科学导论、程序设计导论、程序设计实践。必修课:离散数学、概率与统计、算法分析

建立一个图书馆管理系统的数据库(大运河沿岸图书馆将共建共享文献资源)

来源:光明日报日前,来自京杭大运河沿岸城市公共图书馆的32位馆长及代表齐聚浙江嘉兴,就大运河文献资源共建共享达成共识。大家认为,沿岸8个省(市)近40个城市(区)的公共图书馆有责任、有义务进行系统收集、整理...

有效的图书馆管理系统软件(图书馆数字信息化管理管理方法解决方案-RFID电子技术管理系统)

图书馆使用RFID电子技术管理系统的核心需要使用到RFID电子标签和RFID手持PDA,然后再结合数据库以及软件管理系统来实现图书馆自助借还、图书盘点、图书上架、图书检索、图书防盗、借阅证管理、图书证发放、馆藏信息统计等...

手持扫描器(飞阳手持式一维条码扫描器在图书馆的应用,使图书管理更有效率)

...率上、管理上的好处;例如有的图书上的条码能够链接到数据库和书目记录,图书的管理

环境设计(岭师美术学院举办环境设计作品展)

...的作品是该院环境设计专业的阶段性教学成果,展览分为课程成果展、实物模型和竞赛作品展3个板块,共展出了2019级、2020级学生以“探索与积累”为主题的课程作品48件,2019级、2020级学

环境设计(岭师美术学院举办环境设计作品展)

...的作品是该院环境设计专业的阶段性教学成果,展览分为课程成果展、实物模型和竞赛作品展3个板块,共展出了2019级、2020级学生以“探索与积累”为主题的课程作品48件,2019级、2020级学

环境设计(岭师美术学院举办环境设计作品展)

...的作品是该院环境设计专业的阶段性教学成果,展览分为课程成果展、实物模型和竞赛作品展3个板块,共展出了2019级、2020级学生以“探索与积累”为主题的课程作品48件,2019级、2020级学

武清家具标牌(关于“天津市区级公共图书馆总分馆制建设LOGO设计”征集的公告)

一、活动背景根据《关于推进天津市区级文化馆图书馆总分馆制建设的实施意见》的相关要求,2018年天津市将大力推进区级公共图书馆总分馆制建设工作,至2020年,本市将建立起以区级图书馆为总馆、以乡镇(街道)综合性文...

气源三联件工作原理(机械设计(课程)——气动系统的原理及设计)

这篇文章给大家分享气动设计方面的知识,气动系统是设备尤其是机床加工中心设备的必备系统,例如立式加工中心上的打刀缸,刀库的倒刀,气动吹扫等,这些附件都是需要气动配合的使用的,所以就单机设备而言,气动系统...

平面设计机构培训(宁波平面设计培训班_系统学平面设计课程)

平‌‌面设计师未来发展前景:平面设计的未来前景有着无限的可能性,将会成为一个巨大的产业。因为无论是我们生活用品、办公用品、服饰、影视产业、创意产业等等任何领域,设计上从产品到美观,平面设计都在影响着我...