本文共 3934 字,大约阅读时间需要 13 分钟。
——————————————————————前言————————————————————————————
本节讲解使用flask-sqlalchemy扩展管理数据库。
————————————————————————————————————————————————————
&pip install flask-sqlalchemy
1. 创建表
from hello import db
db.create_all()
2.更新表
db.drop_all()
db.create_all()
3. 插入行
from hello import Role, User
admin_role = Role(name='admin')
mod_role = Role(name='moderator')
user_role = Role(name='user')
user_john = User(username='john', role=admin_role)
user_susan = User(username='susan', role=user_role)
user_david = User(username='david', role=user_role)
id属性是由数据库管理的, 如果现在执行print(user_role.id)会返回None, 因为用户和角色还未提交到数据库中。
4.把用户和角色加入会话
db.session.add(admin_role) #加一个
db.session.add_all([admin_role, mod_role, user_role, user_john, user_susan, user_david]) #一起加
5.提交会话, 把会话中的记录写入数据库
db.session.commit()
再次执行print(user_role.id)便可得到id
6.修改行
admin_role.name = 'Administrator'
db.session.add(admin_role)
db.session.commit()
7.删除行
db.session.delete(mod_role)
db.session.commit()
8.查询行
Role.query.all() #查询所有角色, 返回角色列表
User.query.all() #查询所有用户, 返回用户列表
User.query.filter_by(role=user_role).all() #查询所有角色为user_role的用户, 返回用户列表
str( User.query.filter_by(role=user_role) ) #查看数据库查询的sql语句
#如果我们关掉了终端, 再重新打开, 要找角色为用户的第一个用户
from hello import User
user = User.query.filter_by(role=user_role).first()
users = user_role.users() #返回角色user_role对应的所有用户
users[0].role #返回第一个用户的角色
添加完的数据库如图所示:
roles表
users表
三. 修改hello.py脚本
import osfrom flask_sqlalchemy import SQLAlchemybasedir = os.path.abspath(os.path.dirname(__file__)) #hello.py脚本文件所处目录app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'sqlite.data') #设置数据库urlapp.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True #数据库的改动在请求后自动提交app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False #为了消除警告, 具体作用不明db = SQLAlchemy(app) #初始化扩展class Role(db.Model): #Role表 __tablename__ = 'roles' #设置表名 id = db.Column(db.Integer, primary_key=True) #设置主键, 一参数表示属性值的类型, 二表示该属性为表的主键 name = db.Column(db.String(64), unique=True) #unique表示该属性值不可重复出现 users = db.relationship('User', backref='role', lazy='dynamic') class User(db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64), unique=True, index=True) #index设为True表示添加索引, 提高查询效率 role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))#两行红色的代码表示两个表是一对多关系, 一个角色对应多个用户, 一个用户只能对应一个角色。#role_id是User表中的外键, db.ForeignKey('roles.id')表示该属性的值为roles表中的id值。#角色实例访问users属性可以得到与该角色相关的所有用户, 第一个参数表明与之联系的表, 第二个参数反向为User实例添加#了一个role属性, User实例访问role时可以得到与之对应的角色实例, lazy参数当角色实例访问users属性时可以禁止其自动查#询, 从而采取过滤器进行条件查询。@app.route('/', methods=['GET', 'POST'])def index(): form = NameForm() if form.validate_on_submit(): #只有请求为post请求并web表单数据通过验证函数时为True #查看用户输入的用户在数据库中是否存在, 如果不存在创建用户, 标识为未知, 存在的话标识为已知 user = User.query.filter_by(username=form.name.data).first() if not user: user = User(username=form.name.data) db.session.add(user) session['known'] = False else: session['known'] = True #看此次输入的用户是否为上次输入的用户, 如果不是则渲染flash消息 oldname = session.get('name') if oldname is not None and oldname != form.name.data: flash('Look like your name has changed!') session['name'] = form.name.data #在会话中保存表单中的用户名 for.name.data = '' return redirect(url_for('index')) #重定向 return render_template('index.thml', name=session.get('name'), form=form, known=session.get('known')) #返回响应
{% extends 'base.html' %}{% import 'bootstrap/wtf.html' as wtf %}{% block title %}Flasky{% endblock %}{% block page_content %}{ { wtf.quick_form(form) }}{% endblock %}Hello, {% if name %} { { name }} {% else %} Stranger{% endif %} !
{% if not known %}nice to meet you!
{% else %}happy to meet you again!
{% endif%}
五. 效果展示
地址栏输入根地址并回车
文本框输入Dave并点击提交按钮
上步操作后数据库的变化, 多了一个名为Dave的用户
再次输入Dave时浏览器界面的变化
以上几步效果展示可以结合视图函数来分析。