自定义模型类
本篇章介绍Flask自定义模型类的概念,以及写一个快速入门的示例,基本内容如下:
- 定义两个模型类,并创建数据库表
- 创建数据,写入数据库
- 编写模板以及视图函数,在页面展示数据
定义模型
模型表示程序使用的数据实体,在Flask-SQLAlchemy中,模型一般是Python类,继承自db.Model,db是SQLAlchemy类的实例,代表程序使用的数据库。
类中的属性对应数据库表中的列。id为主键,是由Flask-SQLAlchemy管理。db.Column类构造函数的第一个参数是数据库列和模型属性类型。
如下示例:定义了两个模型类,作者和书名。
代码语言:javascript复制from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import pymysql
pymysql.install_as_MySQLdb()
app = Flask(__name__)
class Config(object):
"""配置参数"""
# 设置连接数据库的URL
user = 'root'
password = '*********'
database = 'flask_ex'
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://%s:%s@127.0.0.1:3306/%s' % (user,password,database)
# 设置sqlalchemy自动更跟踪数据库
SQLALCHEMY_TRACK_MODIFICATIONS = True
# 查询时会显示原始SQL语句
# app.config['SQLALCHEMY_ECHO'] = True
# 禁止自动提交数据处理
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = False
# 读取配置
app.config.from_object(Config)
# 创建数据库sqlalchemy工具对象
db = SQLAlchemy(app)
#定义模型类-作者
class Author(db.Model):
__tablename__ = 'author'
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(32),unique=True)
email = db.Column(db.String(64))
au_book = db.relationship('Book',backref='author')
def __str__(self):
return 'Author:%s' %self.name
#定义模型类-书名
class Book(db.Model):
__tablename__ = 'books'
id = db.Column(db.Integer,primary_key=True)
info = db.Column(db.String(32),unique=True)
leader = db.Column(db.String(32))
au_book = db.Column(db.Integer,db.ForeignKey('author.id'))
def __str__(self):
return 'Book:%s,%s'%(self.info,self.lead)
if __name__ == '__main__':
# 删除所有表
db.drop_all()
# 创建所有表
db.create_all()
执行脚本之后,到mysql中查看表结构如下。
创建表 db.create_all()
代码语言:javascript复制mysql> show tables;
--------------------
| Tables_in_flask_ex |
--------------------
| author |
| books |
--------------------
4 rows in set (0.00 sec)
mysql>
查看author表结构 desc author
代码语言:javascript复制mysql> desc author;
------- ------------- ------ ----- --------- ----------------
| Field | Type | Null | Key | Default | Extra |
------- ------------- ------ ----- --------- ----------------
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(32) | YES | UNI | NULL | |
| email | varchar(64) | YES | | NULL | |
------- ------------- ------ ----- --------- ----------------
3 rows in set (0.00 sec)
查看books表结构 desc books
代码语言:javascript复制mysql> desc books;
--------- ------------- ------ ----- --------- ----------------
| Field | Type | Null | Key | Default | Extra |
--------- ------------- ------ ----- --------- ----------------
| id | int(11) | NO | PRI | NULL | auto_increment |
| info | varchar(32) | YES | UNI | NULL | |
| leader | varchar(32) | YES | | NULL | |
| au_book | int(11) | YES | MUL | NULL | |
--------- ------------- ------ ----- --------- ----------------
4 rows in set (0.00 sec)
创建数据
代码语言:javascript复制...
if __name__ == '__main__':
# 生成数据
author_1 = Author(name='我吃西红柿', email='xihongshi@163.com')
author_2 = Author(name='萧潜', email='xiaoqian@126.com')
author_3 = Author(name='唐家三少', email='sanshao@163.com')
book_1 = Book(info='吞噬星空', leader='罗峰')
book_2 = Book(info='寸芒', leader='李杨')
book_3 = Book(info='飘渺之旅', leader='李强')
book_4 = Book(info='冰火魔厨', leader='融念冰')
# 把数据提交给用户会话
db.session.add_all([author_1, author_2, author_3, book_1, book_2, book_3, book_4])
# 提交会话
db.session.commit()
在main方法下创建多个作者以及书本的数据,执行脚本后,查看mysql数据,如下:
代码语言:javascript复制mysql> select * from author;
---- ----------------- -------------------
| id | name | email |
---- ----------------- -------------------
| 1 | 我吃西红柿 | xihongshi@163.com |
| 2 | 萧潜 | xiaoqian@126.com |
| 3 | 唐家三少 | sanshao@163.com |
---- ----------------- -------------------
3 rows in set (0.00 sec)
mysql> select * from books;
---- -------------- ----------- ---------
| id | info | leader | au_book |
---- -------------- ----------- ---------
| 1 | 吞噬星空 | 罗峰 | NULL |
| 2 | 寸芒 | 李杨 | NULL |
| 3 | 飘渺之旅 | 李强 | NULL |
| 4 | 冰火魔厨 | 融念冰 | NULL |
---- -------------- ----------- ---------
4 rows in set (0.00 sec)
mysql>
使用 flask_wtf 编写视图函数的表单
1.编写完整flask应用,包含视图函数
代码语言:javascript复制from flask import Flask,render_template,url_for,redirect,request
from flask_sqlalchemy import SQLAlchemy
import pymysql
pymysql.install_as_MySQLdb()
# 导入Flask-WTF表单
from flask_wtf import FlaskForm
# 导入表单所需要的字段类型
from wtforms import StringField, PasswordField, SubmitField
# 导入表单的验证器
from wtforms.validators import DataRequired, EqualTo
# 启动命令的管理类
from flask_script import Manager
app = Flask(__name__)
class Config(object):
"""配置参数"""
# 设置连接数据库的URL
user = 'root'
password = '*************'
database = 'flask_ex'
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://%s:%s@127.0.0.1:3306/%s' % (user,password,database)
# 设置sqlalchemy自动更跟踪数据库
SQLALCHEMY_TRACK_MODIFICATIONS = True
# 查询时会显示原始SQL语句
# app.config['SQLALCHEMY_ECHO'] = True
# 禁止自动提交数据处理
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = False
# 设置密钥,用于csrf_token的加解密
app.config["SECRET_KEY"] = "xhosd6f982yfhowefy29f"
# 读取配置
app.config.from_object(Config)
# 创建数据库sqlalchemy工具对象
db = SQLAlchemy(app)
#定义模型类-作者
class Author(db.Model):
__tablename__ = 'author'
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(32),unique=True)
email = db.Column(db.String(64))
au_book = db.relationship('Book',backref='author')
def __str__(self):
return 'Author:%s' %self.name
#定义模型类-书名
class Book(db.Model):
__tablename__ = 'books'
id = db.Column(db.Integer,primary_key=True)
info = db.Column(db.String(32),unique=True)
leader = db.Column(db.String(32))
au_book = db.Column(db.Integer,db.ForeignKey('author.id'))
def __str__(self):
return 'Book:%s,%s'%(self.info,self.leader)
# 定义表单的模型类,用来添加书本以及作者数据
class AddAuthorBook(FlaskForm):
"""自定义的注册表单模型类"""
# DataRequired 保证数据必须填写,并且不能为空
author_name = StringField(label="作者名称", validators=[DataRequired("作者名称不能为空")]) # 参数:名字,验证器列表
book_info = StringField(label="书本信息", validators=[DataRequired("书本信息不能为空")])
submit = SubmitField(label="添加")
@app.route('/',methods=['GET','POST'])
def index():
#查询所有作者和书名信息
authors = Author.query.all()
books = Book.query.all()
#创建表单对象
form = AddAuthorBook()
if form.validate_on_submit():
#获取表单输入数据
author_name = form.author_name.data
book_info = form.book_info.data
#把表单数据存入模型类
db_author = Author(name=author_name)
db_book = Book(info=book_info)
db_book.leader = author_name
db_book.au_book = db_author.id
#提交会话
db.session.add_all([db_author,db_book])
db.session.commit()
#添加数据后,再次查询所有作者和书名信息
authors = Author.query.all()
books = Book.query.all()
return render_template('index.html',author=authors,book=books,form=form)
else:
if request.method=='GET':
render_template('index.html', author=authors, book=books,form=form)
return render_template('index.html',author=authors,book=books,form=form)
#删除作者
@app.route('/delete_author<id>')
def delete_author(id):
print('delete author id = %s' % id)
#精确查询需要删除的作者id
author = Author.query.get(id)
db.session.delete(author)
db.session.commit()
#直接重定向到index视图函数
return redirect(url_for('index'))
#删除书名
@app.route('/delete_book<id>')
def delete_book(id):
print('delete book id = %s' % id)
#精确查询需要删除的书名id
book = Book.query.get(id)
db.session.delete(book)
db.session.commit()
#直接重定向到index视图函数
return redirect(url_for('index'))
if __name__ == '__main__':
# 创建Manager管理类的对象
manager = Manager(app)
# 通过管理对象来启动flask
manager.run()
2.设置index.html模板
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>玄幻系列</h1>
<form method="post">
{{ form.csrf_token }}
<p>作者:{{ form.author_name }}</p>
<p>书名:{{ form.book_info }}</p>
<p>{{ form.submit }}</p>
</form>
<hr>
<ul>
{% for item in author %}
<li>{{ item }}</li><a href='/delete_author{{ item.id }}'>删除</a>
{% endfor %}
</ul>
<hr>
<ul>
{% for item in book %}
<li>{{ item }}</li><a href='/delete_book{{ item.id }}'>删除</a>
{% endfor %}
</ul>
</body>
</html>
3.执行python3 db_demo2.py runserver
启动服务后,进行功能测试
从上面的几个示例,基本清楚讲解了模型类如何定义,表单如何设置,模板中如何展示数据,表单如何提交数据,数据如何设置删除等功能。