一对多模型的增加和删除

后端实现:

from flask import Flask
from flask import flash
from flask import redirect
from flask import render_template
from flask import request
from flask import url_for
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import InputRequired app = Flask(__name__)
app.secret_key = "asdfdf" # 配置数据库
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql://root:mysql@127.0.0.1:3306/booktest"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) class AddBookForm(FlaskForm):
"""自定义添加书籍的表单"""
author = StringField('作者:', validators=[InputRequired('请输入作者')])
book = StringField('书名:', validators=[InputRequired('请输入书名')])
submit = SubmitField('添加') class Author(db.Model):
"""作者模型:一的一方"""
__tablename__ = "authors"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True) # 定义属性,以便作者模型可以直接通过该属性访问其多的一方的数据(书的数据)
# backref 给 Book 也添加了一个 author 的属性,可以通过 book.author 获取 book 所对应的作者信息
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)
# 记录一的一方的id作为外键
author_id = db.Column(db.Integer, db.ForeignKey(Author.id)) @app.route('/delete_author/<author_id>')
def delete_author(author_id):
"""删除作者以及作者所有的书籍""" try:
author = Author.query.get(author_id)
except Exception as e:
print(e)
return "查询错误" if not author:
return "作者不存在" # 删除作者及其所有书籍 try:
# 先删除书籍
Book.query.filter(Book.author_id == author_id).delete()
# 再删除指定作者
db.session.delete(author)
db.session.commit()
except Exception as e:
print(e)
db.session.rollback()
return "删除失败" return redirect(url_for('index')) @app.route('/delete_book/<book_id>')
def delete_book(book_id):
"""删除书籍"""
try:
book = Book.query.get(book_id)
except Exception as e:
print(e)
return "查询错误" if not book:
return "书籍不存在" try:
db.session.delete(book)
db.session.commit()
except Exception as e:
print(e)
db.session.rollback()
return '删除失败' return redirect(url_for('index')) @app.route('/', methods=['get', 'post'])
def index():
"""返回首页""" book_form = AddBookForm() # 如果book_form可以被提交
if book_form.validate_on_submit():
# 1. 取出表单中数据
author_name = book_form.author.data
book_name = book_form.book.data # 2. 做具体业务逻辑代码实现
# 2.1 查询指定名字的作者
author = Author.query.filter(Author.name == author_name).first()
# if 指定名字的作者不存在:
if not author:
try:
# 添加作者信息到数据库
# 初始化作者的模型对象
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()
except Exception as e:
db.session.rollback()
print(e)
flash("添加失败")
else:
book = Book.query.filter(Book.name == book_name).first() if not book:
try:
# 添加书籍信息到数据库(指定其作者)
book = Book(name=book_name, author_id=author.id)
db.session.add(book)
db.session.commit()
except Exception as e:
print(e)
flash("添加失败")
else:
flash("已存在") else:
if request.method == "POST":
flash('参数错误') # 1. 查询数据
authors = Author.query.all()
# 2. 将数据传入到模板中进行渲染返回
return render_template('demo1_bookDemo.html', authors=authors, form=book_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)

前端实现:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <h1>图书管理</h1> <form method="post">
{{ form.csrf_token() }}<br/>
{{ form.author.label }}{{ form.author }}<br/>
{{ form.book.label }}{{ form.book }}<br/>
{{ form.submit }}<br/> {% for message in get_flashed_messages() %}
{{ message }}
{% endfor %} </form> <hr> <ul>
{% for author in authors %}
<li>{{ author.name }}<a href="/delete_author/{{ author.id }}">删除</a></li>
<ul>
{% for book in author.books %}
<li>{{ book.name }}<a href="/delete_book/{{ book.id }}">删除</a></li></li>
{% endfor %}
</ul>
{% endfor %}
</ul> </body>
</html>

Flask--(一对多demo)作者书籍模型的更多相关文章

  1. Python之Flask框架项目Demo入门

    Python+Flask框架项目Demo入门 本例子用到了 Flask+蓝图+Flask-Login+SQLAlchemy+WTForms+PyMySQL相关架构 Flask Web框架介绍 Flas ...

  2. Flask Restful Small Demo

    参考: http://www.pythondoc.com/flask-restful/first.html 什么是Rest Client-Server:服务器端与客户端分离. Stateless(无状 ...

  3. django一对多、多对多模型、自关联的建立

    # 原创,转载请留言联系 一对多模型 一对多的关系,例如员工跟部门.一个部门有多个员工.那么在django怎么建立这种表关系呢? 其实就是利用外键,在多的一方,字段指定外键即可.例如员工和部门,员工是 ...

  4. Flask简介,安装,demo,快速入门

    1.Flask简介 Flask是一个相对于Django而言轻量级的Web框架. 和Django大包大揽不同,Flask建立于一系列的开源软件包之上,这其中 最主要的是WSGI应用开发库Werkzeug ...

  5. Flask + flask_sqlalchemy + jq 完成书籍展示、新增、删除功能

    后端代码 from flask import Flask, render_template, request, jsonify from flask_wtf.csrf import CSRFProte ...

  6. 解析Tensorflow官方PTB模型的demo

    RNN 模型作为一个可以学习时间序列的模型被认为是深度学习中比较重要的一类模型.在Tensorflow的官方教程中,有两个与之相关的模型被实现出来.第一个模型是围绕着Zaremba的论文Recurre ...

  7. WEB框架-Django框架学习(二)- 模型层

    今日份整理为模型层 1.ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库, ...

  8. web框架开发-Django模型层(2)-多表操作

    很重要,都是精华 多表关系模型 一对一 一旦确定表关系是一对一,在两张表中的任意一张表中建立关联字段+Unique 一对多 一旦确定表关系是一对多,创建关联字段在多的表中 多对多 一旦确定表关系是多对 ...

  9. Django模型层-多表操作

    多表操作 一.创建模型 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是 ...

随机推荐

  1. HTML中引用外部JS文件失效原因

    今天在练习中碰到“引用外部的一个js文件但是却失效”的情况,实在不懂,百度后才知是引用的位置不对,错误的代码如下: <head> <meta charset="UTF-8& ...

  2. 数字证书、SSL、HTTPS及在Nginx中的配置

    一.什么是 RSA.SSL.HTTPS RSA:它是非对称加密算法的一种,而且是最常用的一种.它的理论基础是:计算两个大质数的乘积非常简单,而对该乘积进行因子分解就非常困难.而且 这两个质数越大,对其 ...

  3. lumion制作海上明月5.29

    点击海洋系统,打开海洋系统的开关,点击Q提升视线.按住shift提升海的高度,波浪强度调小.风速调高,风向调向朝向我们的方向,这样能看到更多涟漪. 拍照模式,添加特效,添加一个月亮,载增加一个太阳的特 ...

  4. 认识jmeter

    1.jmeter是什么:Apache Jmeter是Apache组织开发的基于java的压力测试工具. Jmeter可用于对服务器.网络或对象模拟巨大的负载,来自不同压力类别下测试他们的强度和分析整体 ...

  5. String 类型equals方法和int == 方法效率比较

    最近写了一个递归方法,在进行比较判断的时候,因为都是integer类型,而integer类型在大于127或者小于-128时会在新建一个,这是因为integer类型的拆装箱机制, 之前没有考虑过equa ...

  6. Charles抓包基本用法

    Charles抓包 浏览器发送和接受的所有请求都可以抓到 1.可以定位问题(如果看不出来是服务端问题还是前端问题) 2.可以设置弱网模式 清空请求按钮如图: 抓包: 1 打开charles,在浏览器中 ...

  7. mpvue 转小程序实践总结

    介绍 Mpvue 是一个使用 Vue.js 开发小程序的前端框架.  基础介绍 框架基于 Vue.js 核心,修改了 Vue.js 的 runtime 和 compiler 实现,使其可以运行在小程序 ...

  8. Css3新属性:calc()

    一.前言 calc()看起来像是javascript中的一个函数,而事实上它是用在Css中的,可以用它来计算长度(宽度或高度),能够自动根据不同尺寸的屏幕自动调接数值,从而很轻松的实现自适应布局展示在 ...

  9. MarkDown学习——基础用法

    目录 MarkDown开发版本MD2All基础用法 此处有代码<a id="top"></a>作为页内锚点 此处是用自动生成的目录 MarkDown是什么M ...

  10. Maven用途

    1.使用Maven编译项目,命令是:“mvncompile” 在命令行中,进入pom.xml所在目录,输入命令即可. 2.使用Maven清理项目,命令是:“mvnclean” 3.使用Maven测试项 ...