安装flask_sqlalchemy模块
一个简单的应用
# 数据库操作
import random
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
#Flask构造函数的第一个参数指定一个引入参数,Flask框架使用这个名字进行静态资源、
#模板、错误信息的定位。除非清楚理解它的作用,通常情况下总应该使用特殊变量__name__
app = Flask(__name__)
# 配置app的数据库信息,
#如果使用的是python3,在mysql后面加上pymysql,root为用户名,westos是数
#据库的密码,ormFlask是库名
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:@localhost/ormFlask'
#如果设置成Ture(默认情况),flask_sqlalchemy将会追踪对象的修改并且
#发送信号。这需要额外的内存,如果不必要的可以禁用他。如果不显示的调
#用它在最新的版本运行环境下会显示警告。
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
#SQLAlchemy函数,将刚刚创建的Flask框架与工程所需要的数据库绑定
#到一起,以实现工程与数据库链接,实现数据操作。
db = SQLAlchemy(app)
#创建一个关于学生的类对应数据库中的一个表
#继承db.Model类,将我们当前创建的映射表和数据库db绑定在一起,
#此时工程文件调用create_all函数后,会自动将绑定后的映射表文
#件创建在数据库文件里。
class Student(db.Model):
#属性对应数据库表中的字段,db.Integer表示数据类型为整型,
#autoincrement=True表示自动增加,primary_key=True表示为
#唯一主键,不可重复
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
name = db.Column(db.String(30))
age = db.Column(db.Integer)
def __init__(self, name, age):
self.name = name
self.age = age
def add(self):
try:
#将对象添加到会话中
db.session.add(self)
#提交会话开始生效
db.session.commit()
return self.id
except Exception as e:
#如果报错则将数据返回不生效
db.session.rollback()
return e
def __repr__(self):
return '<Student: %r %r>' %(self.name, self.age)
#在数据库中创建已经定义的所有的对象对应的表
db.create_all()
#实例化一个表对象,需要传入name和age
stu1=Student(name='westos',age=18)
#将对象加入会话
stu1.add()
#删除所有的对象表
# db.drop_all()
批量添加
#批量生成实例
users=[]
for i in range(20):
stu=Student(name='westos'+str(i),age=i)
users.append(stu)
#批量添加到会话
db.session.add_all(users)
db.session.commit()
复杂一点的应用
需要用到的模块flask_bootstrap
Bootstrap,来自 Twitter,是目前最受欢迎的前端框架。Bootstrap 是基于 HTML、CSS、JAVASCRIPT 的,它简洁灵活,使得 Web 开发更加快捷。
import random
from datetime import datetime
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bootstrap import Bootstrap
app=Flask(__name__)
#连接数据的数据库
app.config['SQLALCHEMY_DATABASE_URI']="mysql+pymysql://root:@127.0.0.1/relormFlask"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
#将app对象绑定到Bootstrap,之后继承Bootstrap之中的base.html,自动使用Bootstrap之中
# 的前端样式
Bootstrap(app)
#实例化db对象
db=SQLAlchemy(app)
# 创建user表
class Users(db.Model):
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
# unique: 指定该列信息是唯一的;
name = db.Column(db.String(50), unique=True)
passwd = db.Column(db.String(50))
# default是默认值l
add_time = db.Column(db.DateTime, default=datetime.now())
#使用外键
role_id = db.Column(db.Integer, db.ForeignKey('role.id'))
# 创建用户角色(超级会员, 会员, 普通会员)
class Role(db.Model):
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
name = db.Column(db.String(50), unique=True)
# 'Users代表的是Role表关联的数据库表'
# backref=“role”: 反向引用;让Users中有role属性, user.role返回的是role对象。
#意义:让Role成为User的一个属性,属性名为role
users = db.relationship('Users', backref='role')
db.create_all()
# # 2. 创建用户角色
role1 = Role(name="超级会员")
role2 = Role(name="会员")
role3 = Role(name="普通会员")
db.session.add_all([role1, role2, role3])
db.session.commit()
#3.创建用户
users=[Users(name='user'+str(i),passwd='westos',role_id=random.choice([1,2,3])) for i in range(20)]
db.session.add_all(users)
db.session.commit()
增删改查
查询
查询数据信息
# 查询所有角色
print(Role.query.all())
#显示会员类型与该会员类型包含的所有用户
roles=Role.query.all()
for role in roles:
print(role.id,role.name,role.users)
根据条件查找符和条件的数据;(filter_by(常用), filter)
1.简单查询
返回所有用户
print(Users.query.all())
2.带条件查询
找到所有超级会员的用户(通过rold_id);
users = Users.query.filter_by(role_id=1).all()
print(users)
#查询符合某一条件的数量
u=Users.query.filter_by(role_id=1).count()
print(u)
#查询第一个符合该条件的用户
u=Users.query.filter_by(role_id=1).first()
print(u)
#打印用户名以3结尾的用户
u=Users.query.filter(Users.name.endswith('3')).all()
print(u)
3.排序查询
#按id(desc())倒序,从第二个开始(offset(2)),打印三个用户(limit(3))
u=Users.query.order_by(Users.id.desc()).offset(2).limit(3).all()
print(u)
4.组合查询
#需要导入模块and_
u=Users.query.filter(and_(Users.id>3 , Users.id<7)).all()
print(u)
u=Users.query.filter(or_(Users.id==3 , Users.id==7)).all()
print(u)
5.分页查询
u=Users.query.paginate(page=2,per_page=4)
print(dir(u))
items:返回当前页的内容列表
has_next:是否还有下一页
has_prev:是否还有上一页
next(error_out=False):返回下一页的Pagination对象
prev(error_out=False):返回上一页的Pagination对象
page:当前页的页码(从1开始)
pages:总页数
per_page:每页显示的数量
prev_num:上一页页码数
next_num:下一页页码数
query:返回创建该Pagination对象的查询对象
total:查询返回的记录总数
插入
1.创建对象
2.以参数形式传递,添加到会话
3.提交会话
注意:这里的会话是SQLAlchemy会话;
删除
1.查询数据
2.从会话中删除
3.提交会话
# u = Users.query.filter_by(id=1).first()
# db.session.delete(u)
# db.session.commit()
更新
1.获取对象
2.给对象属性重新赋值
3.将对象添加到会话
4.提交会话
u = Users.query.filter_by(id=1).first()
print(u.id, u.name, u.add_time)
u.name = "西部开源1"
db.session.add(u)
db.session.commit()
将信息分页显示到前端
models.py
创建用户对象和身份对象
import random
from datetime import datetime
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bootstrap import Bootstrap
from sqlalchemy import and_, or_
app=Flask(__name__)
#连接数据的数据库
app.config['SQLALCHEMY_DATABASE_URI']="mysql+pymysql://root:@127.0.0.1/relormFlask"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
#将app对象绑定到Bootstrap,之后继承Bootstrap之中的base.html,自动使用Bootstrap之中
# 的前端样式
Bootstrap(app)
#实例化db对象
db=SQLAlchemy(app)
# 创建user表
class Users(db.Model):
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
# unique: 指定该列信息是唯一的;
name = db.Column(db.String(50), unique=True)
passwd = db.Column(db.String(50))
# default是默认值l
add_time = db.Column(db.DateTime, default=datetime.now())
#使用外键
role_id = db.Column(db.Integer, db.ForeignKey('role.id'))
# 创建用户角色(超级会员, 会员, 普通会员)
class Role(db.Model):
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
name = db.Column(db.String(50), unique=True)
# 'Users代表的是Role表关联的数据库表'
# backref=“role”: 反向引用;让Users中有role属性, user.role返回的是role对象。
#意义:让Role成为User的一个属性,属性名为role
users = db.relationship('Users', backref='role')
relationsql练习.py
定义视图函数,获取分页信息并传给前端
from flask import Flask,render_template,redirect,url_for
from modesl import Users,Role,app
@app.route('/list/<int:page>')
@app.route('/list/')
def query(page=1):
users=Users.query.paginate(page,per_page=4)
print(users.items)
return render_template('list.html',
users=users)
if __name__ == '__main__':
app.run(host='0.0.0.0',port=9000)
定义一个宏,用来设置跳转页面,
/macro/page.html
{% macro paginate(funame,dataObj) %}
{# 分页信息#}
<ul class="pagination pull-right">
{# 首页 #}
<li><a href="{{ url_for(funame,page=1) }}">首页</a>/li>
{#
上一页信息
1).判断是否有上一页信息;
2).如果有,创建链接
3).如果没有,设为不可点击的链接
#}
{% if dataObj.has_prev %}
<li><a href="{{ url_for(funame,page=dataObj.prev_num) }}">«</a></li>
{% else %}
<li class="disabled"><a href="#">«</a></li>
{% endif %}
{#分布的页数
1).当构造页数时,判断是否为用户访问的页数,如果是则增加页数
2).disable代表用户不可点击的链接
#}
{% for v in dataObj.iter_pages() %}
{% if v==dataObj.page %}
<li class="active"><a href="{{ url_for(funame,page=v) }}">{{ v }}</a></li>
{% elif v==None %}
<li class="disabled"><a href="#">...</a></li>
{% else %}
<li><a href="{{ url_for(funame,page=v) }}">{{ v }}</a></li>
{% endif %}
{% endfor %}
{#
下一页信息
1).判断是否有下一页信息;
2).如果有,创建链接
3).如果没有,设为不可点击的链接
#}
{% if dataObj.has_next %}
<li><a href="{{ url_for(funame,page=dataObj.next_num) }}">»</a></li>
{% else %}
<li class="disabled"><a href="#">»</a></li>
{% endif %}
</ul>
{% endmacro %}
前端显示页面,显示获取到的分页信息,继承定义的宏,在信息表下显示跳转页面号
{% extends 'bootstrap/base.html' %}
{% block title %}用户显示{% endblock %}
{% block content %}
<div class="col-md-8 col-md-offset-2">
<h1>用户显示</h1>
<table class="table table-bordered">
<thead>
<th>用户编号</th>
<th>用户名</th>
<th>用户密码</th>
<th>创建时间</th>
<th>用户类型</th>
{# <th>删除</th>#}
</thead>
{% for user in users.items %}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
<td>{{ user.passwd }}</td>
<td>{{ user.add_time }}</td>
<td>{{ user.role.name }}</td>
</tr>
{% endfor %}
</table>
{# 分页信息#}
{% from 'macro/page.html' import paginate %}
{{ paginate('query', users) }}
</div>
{% endblock %}
运行结果