library.py
1"""
2分析图书馆案例
3
4- 1.数据库配置
5 - 作者模型(一方)
6 - 书籍模型(多方)
7- 2.添加测试数据
8- 3.添加作者,书籍
9- 4.删除作者,删除书籍
10
11"""
12from flask import Flask, render_template, request, redirect,flash
13from flask_sqlalchemy import SQLAlchemy
14from flask_wtf.csrf import CSRFProtect
15
16app = Flask(__name__)
17
18app.config["SECRET_KEY"] = "fdfdfd"
19
20#使用CSRFProtect保护app
21CSRFProtect(app)
22
23#1.设置数据库配置信息
24app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@127.0.0.1:3306/library36"
25app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
26# app.config["SQLALCHEMY_ECHO"] = True #写上之后会在控制台输出对应生成的sql语句
27
28#2.创建SQLAlchemy对象,关联app
29db = SQLAlchemy(app)
30
31#3.编写模型类
32#作者模型(一方)
33class Author(db.Model):
34 __tablename__ = "authors"
35 id = db.Column(db.Integer,primary_key=True)
36 name = db.Column(db.String(32))
37
38 #关系属性
39 books = db.relationship("Book",backref="author")
40
41#书籍模型(多方)
42class Book(db.Model):
43 __tablename__ = "books"
44 id = db.Column(db.Integer,primary_key=True)
45 name = db.Column(db.String(32))
46
47 #外键
48 author_id = db.Column(db.Integer,db.ForeignKey(Author.id))
49 # author_id = db.Column(db.Integer,db.ForeignKey("authors.id")) #和上面的方式等价
50
51
52#4.展示页面
53@app.route('/')
54def show_index():
55 #1.查询所有的作者信息
56 authors = Author.query.all()
57
58 #2.携带作者信息,渲染页面
59 return render_template("file01library.html",authors=authors)
60
61#5.添加数据
62@app.route('/add_data', methods=["POST"])
63def add_data():
64 #1.获取提交的数据
65 author_name = request.form.get("author")
66 book_name = request.form.get("book")
67
68 #1.1判断输入的内容是否为空
69 if not all([author_name,book_name]):
70 flash("作者或者书籍不能为空")
71 return redirect("/")
72
73 #2.根据作者的信息,查询作者对象
74 author = Author.query.filter(Author.name == author_name).first()
75
76 #3.判断作者是否存在
77 if author:
78
79 #4.通过书籍名称查询书籍对象, 获取该作者,有没有写过该书
80 book = Book.query.filter(Book.name == book_name,Book.author_id == author.id).first()
81
82 #5.判断书籍对象是否存在
83 if book:
84 flash("该作者,有该书了")
85 else:
86 #创建书籍对象,添加到数据库
87 book = Book(name=book_name,author_id=author.id)
88 db.session.add(book)
89 db.session.commit()
90 else:
91 #创建作者,对象,添加到书籍库
92 author = Author(name=author_name)
93 db.session.add(author)
94 db.session.commit()
95
96 # 创建书籍对象,添加到数据库
97 book = Book(name=book_name, author_id=author.id)
98 db.session.add(book)
99 db.session.commit()
100
101 #6.重定向到首页展示
102 return redirect("/")
103
104#6.删除书籍
105@app.route('/delete_book/<int:book_id>')
106def delete_book(book_id):
107 #1.根据书籍编号取出书籍对象
108 book = Book.query.get(book_id)
109
110 #2.删除书籍
111 db.session.delete(book)
112 db.session.commit()
113
114 #3.重定向到页面显示
115 return redirect("/")
116
117#7.删除作者
118@app.route('/delete_author/<int:author_id>')
119def delete_author(author_id):
120 #1.根据作者编号取出作者对象
121 author = Author.query.get(author_id)
122
123 #2.遍历作者书籍,删除
124 for book in author.books:
125 db.session.delete(book)
126
127 #3.删除作者,提交数据库
128 db.session.delete(author)
129 db.session.commit()
130
131 #4.重定向展示页面
132 return redirect("/")
133
134
135if __name__ == '__main__':
136 #为了演示方便,先删除,后创建
137 db.drop_all()
138 db.create_all()
139
140 #添加测试数据库
141 # 生成数据
142 au1 = Author(name='老王')
143 au2 = Author(name='老尹')
144 au3 = Author(name='老刘')
145 # 把数据提交给用户会话
146 db.session.add_all([au1, au2, au3])
147 # 提交会话
148 db.session.commit()
149
150
151 bk1 = Book(name='老王回忆录', author_id=au1.id)
152 bk2 = Book(name='我读书少,你别骗我', author_id=au1.id)
153 bk3 = Book(name='如何才能让自己更骚', author_id=au2.id)
154 bk4 = Book(name='怎样征服美丽少女', author_id=au3.id)
155 bk5 = Book(name='如何征服英俊少男', author_id=au3.id)
156 # 把数据提交给用户会话
157 db.session.add_all([bk1, bk2, bk3, bk4, bk5])
158 # 提交会话
159 db.session.commit()
160
161
162 app.run(debug=True)
library.html
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <title>Title</title>
6</head>
7<body>
8
9{# action: 提交到的地址, method: 表示提交的方式 #}
10<form action="/add_data" method="post">
11
12 {# 设置隐藏字段csrf_token , 只要使用了CSRFProtect,然后使用模板渲染的时候就可以直接使用csrf_token()方法#}
13 <input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
14
15 作者: <input type="text" name="author"><br>
16 书籍: <input type="text" name="book"><br>
17 <input type="submit" value="添加"><br>
18 {% for message in get_flashed_messages() %}
19 <span style="color: red;">{{ message }}</span>
20 {% endfor %}
21
22</form>
23
24<hr>
25
26{# 数据展示 #}
27<ul>
28 {# 遍历作者 #}
29 {% for author in authors %}
30{# <li>作者: {{ author.name }} <a href="/delete_author/{{ author.id }}">删除</a></li>#}
31 <li>作者: {{ author.name }} <a href="{{ url_for("delete_author",author_id=author.id) }}">删除</a></li>
32
33 {# 遍历作者的书籍 #}
34 <ul>
35 {% for book in author.books %}
36 <li>书籍: {{ book.name }} <a href="/delete_book/{{ book.id }}">删除</a></li>
37 {% endfor %}
38
39 </ul>
40 {% endfor %}
41
42</ul>
43
44
45
46</body>
47</html>
ORM相关操作流程
orm.py
1"""
2操作流程:
3
4- 1.安装扩展
5 - pip install flask_sqlalchemy
6 - pip install flask_mysqldb / pymysql
7- 2.设置数据库的配置信息
8- 3.创建sqlalchemy对象db,关联app
9- 4.编写模型类,字段,继承自db.Model,
10- 5.操作数据库
11 - 增删改
12 - 查询
13"""
14from flask import Flask
15from flask_sqlalchemy import SQLAlchemy
16
17app = Flask(__name__)
18
19#2.设置数据库的配置信息
20#设置数据库的链接信息,
21app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@127.0.0.1:3306/data36"
22#该字段增加了大量的开销,会被禁用,建议设置为False
23app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
24
25
26#3.创建sqlalchemy对象db,关联app
27db = SQLAlchemy(app)
28
29# 4.编写模型类,字段,继承自db.Model
30class Student(db.Model):
31 __tablename__ = "students"
32 #主键, 参数1: 表示id的类型, 参数2: 表示id的约束类型
33 id = db.Column(db.Integer,primary_key=True)
34 name = db.Column(db.String(32))
35
36@app.route('/')
37def hello_world():
38
39 return "helloworld"
40
41if __name__ == '__main__':
42
43 #删除继承自db.Model的表
44 db.drop_all()
45
46 #5.创建数据库的表,创建的是继承自db.Model的表
47 db.create_all()
48
49 app.run(debug=True)
数据库的增删改
role_user.py
1"""
2增删改
3
4- 全部都是使用db.session操作
5- 常见方法:
6 - db.session.add(obj) 添加单个对象
7 - db.session.add_all([obj1,obj2]) 添加多个对象
8 - db.session.delete(obj) 删除单个对象
9 - db.session.commit() 提交会话
10 - db.drop_all() 删除继承自db.Model所有表
11 - db.create_all() :创建继承自db.Model的所有表
12 - 其他:
13 - db.session.rollback() 回滚
14 - db.session.remove() 移除会话
15 - 案例: 编写两个模型类, 一个角色模型类, 还有一个用户模型类
16 - 关系: 一对多
17
18"""
19from flask import Flask
20from flask_sqlalchemy import SQLAlchemy
21
22app = Flask(__name__)
23
24#1.设置数据库的配置信息
25app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@127.0.0.1:3306/data36"
26app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
27
28#2.创建SQLalchemy对象,关联app
29db = SQLAlchemy(app)
30
31#3.编写模型类
32#角色(一方)
33class Role(db.Model):
34 __tablename__ = "roles"
35 id = db.Column(db.Integer,primary_key=True)
36 name = db.Column(db.String(32))
37
38 #如果一个类继承自object那么重写__str__方法即可, 如果是继承自db.Model那么需要重写__repr__方法
39 def __repr__(self):
40 return "<Role:%s>"%self.name
41
42#用户(多方)
43class User(db.Model):
44 __tablename__ = "users"
45 id = db.Column(db.Integer,primary_key=True)
46 name = db.Column(db.String(32))
47
48 #建立外键
49 role_id = db.Column(db.Integer,db.ForeignKey(Role.id))
50
51 #如果一个类继承自object那么重写__str__方法即可, 如果是继承自db.Model那么需要重写__repr__方法
52 def __repr__(self):
53 return "<User:%s>"%self.name
54
55@app.route('/')
56def hello_world():
57
58 return "helloworld"
59
60if __name__ == '__main__':
61
62 #为了演示方便,先删除表,后创建
63 db.drop_all()
64 db.create_all()
65
66 app.run(debug=True)
数据库的查询
role_user_query.py
1"""
2查询
3
4"""
5from flask import Flask
6from flask_sqlalchemy import SQLAlchemy
7
8app = Flask(__name__)
9
10#1.设置数据库的配置信息
11app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@127.0.0.1:3306/data37"
12app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
13app.config["SQLALCHEMY_ECHO"] = True
14
15#2.创建SQLalchemy对象,关联app
16db = SQLAlchemy(app)
17
18#3.编写模型类
19#角色(一方)
20class Role(db.Model):
21 __tablename__ = "roles"
22 id = db.Column(db.Integer,primary_key=True)
23 name = db.Column(db.String(32))
24
25 #给role添加了一个users属性, 那么查询的方式是, role.users
26 #给user添加了一个role属性, 那么查询的方式是, user.role
27 users = db.relationship("User",backref="role",lazy="dynamic")
28
29 #如果一个类继承自object那么重写__str__方法即可, 如果是继承自db.Model那么需要重写__repr__方法
30 def __repr__(self):
31 return "<Role:%s>"%self.name
32
33#用户(多方)
34class User(db.Model):
35 __tablename__ = "users"
36 id = db.Column(db.Integer,primary_key=True)
37 name = db.Column(db.String(32))
38 email = db.Column(db.String(32))
39 password = db.Column(db.String(32))
40
41 #建立外键
42 role_id = db.Column(db.Integer,db.ForeignKey(Role.id))
43
44 #如果一个类继承自object那么重写__str__方法即可, 如果是继承自db.Model那么需要重写__repr__方法
45 def __repr__(self):
46 return "<User:%s,%s,%s,%s>"%(self.id,self.name,self.email,self.password)
47
48@app.route('/')
49def hello_world():
50
51 return "helloworld"
52
53if __name__ == '__main__':
54
55 #为了演示方便,先删除表,后创建
56 db.drop_all()
57 db.create_all()
58
59 # 创建测试数据
60 ro1 = Role(name='admin')
61 db.session.add(ro1)
62 db.session.commit()
63
64 # 再次插入一条数据
65 ro2 = Role(name='user')
66 db.session.add(ro2)
67 db.session.commit()
68
69 # 多条用户数据
70 us1 = User(name='wang', email='wang@163.com', password='123456', role_id=ro1.id)
71 us2 = User(name='zhang', email='zhang@189.com', password='201512', role_id=ro2.id)
72 us3 = User(name='chen', email='chen@126.com', password='987654', role_id=ro2.id)
73 us4 = User(name='zhou', email='zhou@163.com', password='456789', role_id=ro1.id)
74 us5 = User(name='tang', email='tang@itheima.com', password='158104', role_id=ro2.id)
75 us6 = User(name='wu', email='wu@gmail.com', password='5623514', role_id=ro2.id)
76 us7 = User(name='qian', email='qian@gmail.com', password='1543567', role_id=ro1.id)
77 us8 = User(name='liu', email='liu@itheima.com', password='867322', role_id=ro1.id)
78 us9 = User(name='li', email='li@163.com', password='4526342', role_id=ro2.id)
79 us10 = User(name='sun', email='sun@163.com', password='235523', role_id=ro2.id)
80 db.session.add_all([us1, us2, us3, us4, us5, us6, us7, us8, us9, us10])
81 db.session.commit()
82
83 app.run(debug=True)
多对多关系
many_to_many.py
1"""
2多对多关系
3案例: 学生和课程
4"""
5from flask import Flask
6from flask_sqlalchemy import SQLAlchemy
7
8app = Flask(__name__)
9
10#1.设置数据库的配置信息
11app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@localhost:3306/data38"
12app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
13
14#2.创建Sqlalchemy对象,关联app
15db = SQLAlchemy(app)
16
17#3.编写模型类
18
19#中间表
20tb_student_course = db.Table(
21 "tb_student_course",
22 db.Column("student_id",db.Integer,db.ForeignKey("students.id")),
23 db.Column("course_id",db.Integer,db.ForeignKey("courses.id"))
24)
25
26#学生
27class Student(db.Model):
28 __tablename__ = "students"
29 id = db.Column(db.Integer,primary_key=True,autoincrement=True)
30 name = db.Column(db.String(32))
31
32 #关系属性secondary: 使用在多对多种,用来表示二次查询的
33 courses = db.relationship("Course",backref="students",secondary="tb_student_course")
34
35
36 #为了方便输出对象查看,重写__repr__方法
37 def __repr__(self):
38 return "<Student:%s>"%self.name
39
40#课程
41class Course(db.Model):
42 __tablename__ = "courses"
43 id = db.Column(db.Integer,primary_key=True,autoincrement=True)
44 name = db.Column(db.String(32))
45
46 #为了方便输出对象查看,重写__repr__方法
47 def __repr__(self):
48 return "<Student:%s>"%self.name
49
50
51@app.route('/')
52def hello_world():
53
54 return "helloworld"
55
56if __name__ == '__main__':
57
58 #为了演示方便,先删除,后创建
59 db.drop_all()
60 db.create_all()
61
62 # 添加测试数据
63 stu1 = Student(name='张三')
64 stu2 = Student(name='李四')
65 stu3 = Student(name='王五')
66
67 cou1 = Course(name='物理')
68 cou2 = Course(name='化学')
69 cou3 = Course(name='生物')
70
71 stu1.courses = [cou2, cou3]
72 stu2.courses = [cou2]
73 stu3.courses = [cou1, cou2, cou3]
74
75 db.session.add_all([stu1, stu2, stu2])
76 db.session.add_all([cou1, cou2, cou3])
77
78 db.session.commit()
79
80
81 app.run(debug=True)
数据库迁移
flask_migrate.py
1"""
2数据库迁移[掌握]
3
4- 目的: 当数据库的表结构发生变化之后,如果直接删除原有的数据,再添加新的数据,有可能导致数据丢失
5- 注意点:
6 - 1.是为了备份表结构,而不是数据
7 - 2.如果想要备份数据,需要使用工具,navicat,mysqlworkbench,等等
8- 操作流程:
9 - 1.安装扩展
10 - pip install flask_script
11 - pip install flask_migrate
12 - 2.导入三个类
13 - from flask_script import Manager
14 - from flask_migrate import Migrate, MigrateCommand
15 - 3.通过Manager类创建对象manager,管理app
16 - manager = Manager(app)
17 - 4.使用Migrate,关联db,app
18 - Migrate(app,db)
19 - 5.给manager添加一条操作命令
20 - manager.add_command("db",MigrateCommand)
21 - 相关迁移命令:
22 - 生成迁移文件夹
23 - python xxx.py db init
24 - 将模型类生成迁移脚本
25 - python xxx.py db migrate -m '注释'
26 - 将迁移脚本更新到数据库中
27 - python xxx.py db upgrade
28
29"""
30
31from flask import Flask
32from flask_script import Manager
33from flask_migrate import Migrate,MigrateCommand
34from flask_sqlalchemy import SQLAlchemy
35
36app = Flask(__name__)
37
38#设置数据库配置信息
39app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@localhost:3306/data39"
40app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
41
42#创建SQLAlchemy对象,关联app
43db = SQLAlchemy(app)
44
45#3.通过Manager类创建对象manager,管理app
46manager = Manager(app)
47
48# 4.使用Migrate,关联db,app
49Migrate(app,db)
50
51# 5.给manager添加一条操作命令
52manager.add_command("db",MigrateCommand)
53
54# 6.编写模型类
55class Student(db.Model):
56 id = db.Column(db.Integer,primary_key=True)
57 name = db.Column(db.String(32))
58 age = db.Column(db.Integer)
59
60
61@app.route('/')
62def hello_world():
63
64 return "helloworld"
65
66if __name__ == '__main__':
67 manager.run()