前言:本文是学习网易微专业的《python全栈工程师 - Flask高级建站》课程的笔记,欢迎学习交流。同时感谢老师们的精彩传授!
user = User(field1 = value1, field2 = value2, ...)
db.session.add(user)
db.session.commit()
注:要提高程序的性能,应该减少跟数据库打交道的次数
批量生成100个用户:
# 批量创建用户
def createBatchUsers():
words = list("abcdefghijklmnopqrstuvwxyz")
citys = ["010", "021", "0512"]
mylikes = ["睡觉", "旅游", "看书", "唱歌"]
import random
for i in range(100):
random.shuffle(words)
username = "".join(words[:6])
sex = random.randint(0, 1)
city = citys[random.randint(0, 2)]
random.shuffle(mylikes)
mylike = "|".join(mylikes[:random.randint(0, 3)])
user = User(
realname = "-",
username = username,
password = "",
sex = sex,
mylike = mylike,
city = city,
intro = ""
)
db.session.add(user)
db.session.commit()
上节课创建的用户数据模型:
# 创建用户数据模型
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String)
password = db.Column(db.String)
realname = db.Column(db.String)
sex = db.Column(db.Integer)
mylike = db.Column(db.String)
city = db.Column(db.String)
intro = db.Column(db.String)
实操步骤:
Step1
.在虚拟环境中运行下面命令进行shell环境:
flask shell
Step2
.在shell环境中导入createBatchUsers并运行:
>>> from app import createBatchUsers
>>> createBatchUsers()
Step3
.新开一个命令行窗口,在虚拟环境中运行下面命令,打开sqlite
数据库的web界面:
sqlite_web my.db
通过打开的网页窗口,我们可以看到新增虚拟用户(我这里是运行了两次,加注册了一个,所以一共是201个数据)
查询通过模型类的query
对象方法:Model.query.<查询方法>
查询方法 | 说明 |
---|---|
all() | 获得所有记录 |
first() | 获得第一条记录,找不到返回None |
one() | 返回唯一 一 条记录,如果存在多条或者没有则报错 |
get(id) | 传入主键id,返回与主键值匹配的记录,无匹配返回None |
count() | 返回查询结果总数 |
one_or_none | 与one()一样,如果结果不唯一,返回None |
模版:需要提供一个用户列表显示模版
路由:提供一个访问路径。比如:@app.route("/userlist")
视图函数:通过模型对象查询结果,并将结果赋给模版变量
新建文件:templates/user/edit_user.html
和templates/user/user_list.html
user_list.html
内容如下:
{% extends "base.html" %}
{% block style %}
input[type='number']{
width: 100px;
}
.btn{
margin-right: 30px;
}
{% endblock %}
{% block content %}
<div class="container-fluid">
<div class="row">
<div class="col-md-2 hidden-xs hidden-sm">
<ul class="nav nav-pills " id="left_menu">
<li class="active"><a href="">标准模块a>li>
<li ><a href="#" data-toggle="dropdown">socket编程a>li>
<li><a href="">异步编程a>li>
<li><a href="">并发编程a>li>
ul>
div>
<div class="col-md-6">
<h3>用户管理h3>
<div class="panel">
<form action="" method="post" class="form-horizontal" >
<div class="form-group">
<label for="q" class="col-xs-2 control-label">关键字label>
<div class="col-xs-10">
<input type="text" name="q" class="form-control">
div>
div>
<div class="form-group">
<label for="field" class="col-xs-2 control-label">查询字段label>
<div class="col-xs-10">
<select name="field" class="form-control">
<option value="realname">查询字段option>
<option value="realname">真实名字option>
<option value="username">用户昵称option>
select>
div>
div>
<div class="form-group">
<label for="sex" class="col-xs-2 control-label">性别label>
<div class="col-xs-2">
<select name="sex" class="form-control">
<option value="1" checked>男option>
<option value="0">女option>
select>
div>
div>
<div class="form-group">
<label for="排序" class="col-xs-2 control-label">排序label>
<div class="col-xs-2">
<select name="order" class="form-control">
<option value="1" checked>按照id升序排序option>
<option value="2">按照id降序排序option>
select>
div>
div>
<div class="form-group ">
<input type="submit" name="search" class="btn btn-primary pull-right" value="立即搜索">
div>
form>
div>
<table class="table">
<tr>
<td>总页数:{{ pages }}/总记录:{{ total }}td>
tr>
table>
<table class="table table-bordered ">
<tr>
<th>用户idth>
<th>用户名th>
<th>真实名th>
<th>性别th>
<th>城市th>
<th>操作th>
tr>
{% for user in users %}
<tr>
<td>{{ user.id }}td>
<td>{{ user.username }}td>
<td>{{ user.realname }}td>
<td>{{ user.sex }}td>
<td>{{ user.city }}td>
<td>
修改a>
删除a>
td>
tr>
{% endfor %}
table>
<ul class="pagination">
{% for page in pageList %}
{% if page!=None %}
<li><a href="?page={{ page }}">{{ page }}a>li>
{% else %}
<li><a href="#">...a>li>
{% endif %}
{% endfor %}
ul>
div>
div>
div>
div>
{% endblock %}
body>
html>
edit_user.html
内容如下:
{% extends "base.html" %}
<html>
<body>
{% block content %}
<div class="container-fluid">
<div class="row">
<div class="main col-md-12 col-lg-12 col-xs-12 col-sm-12" >
<h3>用户信息修改h3>
<div class="body">
<form action="" method="post">
<div class="form-group">
<label for="name">姓名:label>
<input class="form-control" type="text" name="name" id="name" value="{{ user.realname }}" />
div>
<div class="form-group">
<label for="username">用户名:label>
div>
<div class="form-group">
<label class="radio-inline">
女
label>
<label class="radio-inline">
男
label>
div>
<div class="form-group">
<label class="checkbox-inline">
<input type="checkbox" name="like" id="like1"
{% if user.mylike.find("睡觉")!=-1 %} checked {% endif %}
value="睡觉" />睡觉
label>
<label class="checkbox-inline">
<input type="checkbox" name="like" id="like2"
{% if user.mylike.find("旅游")!=-1 %} checked {% endif %}
value="旅游" />旅游
label>
<label class="checkbox-inline">
<input type="checkbox" name="like" id="like3"
{% if user.mylike.find("看书")!=-1 %} checked {% endif %}
value="看书" />看书
label>
<label class="checkbox-inline">
{% if user.mylike.find("唱歌")!=-1 %} checked {% endif %}
<input type="checkbox" name="like" id="like4" value="唱歌" />唱歌
label>
div>
<div class="form-group">
<select name="city">
在app.py
中新增如下视图函数:
@app.route('/userlist', method=['GET'])
def userlist():
users = User.query.all()
return render_template('user/user_list.html', users=users)
(1).删除记录通过db.session.delete(记录对象)
删除
单个删除:
user1 = User.query.get(1)
db.session.delete(user1)
db.session.commit()
即可将id=1的记录删除
批量删除:
users = User.query.all()
[db.session.delete(user) for user in users]
db.session.commit()
(2).路由与视图函数准备,
路由:通常删除需要传递一个被删除对象的id
@app.route("/delete_user/" )
视图函数:
def deleteUser(user_id):
pass
return redirect(用户列表页)
# 删除后返回用户列表页面
在app.py
中新增如下视图函数,记得在文件前面引入redirect
和url_for
:
from flask import redirect, url_for
.
.
.
@app.route("/user_delete/" )
def deleteUser(user_id):
user = User.query.get(user_id)
db.session.delete(user)
db.session.commit()
return redirect(url_for('userList'))
(1).通过模型类查询对象更新记录(U - 更新记录)
比如:
user1 = db.query.get(1)
user1.password = "654321"
db.session.commit()
即可将user1记录的password字段值修改
(2).模版:
修改页面需要的表单与注册页面的表单是一致的,但是需要使用用户当前信息填充表单。
路由:
@app.route("/edit_user/" , methods=["GET", "POST"])
视图函数:
def edit_user(user_id):
if request.method == 'POST':
# 执行修改
return ...
(3).实操步骤:
在文件app.py
中新增如下视图函数:
# 用户信息修改
@app.route("/useredit/" , methods=['GET', 'POST'])
def editUser(user_id):
user = User.query.get(user_id)
if request.method == 'POST':
user.realname = request.form['name']
user.username = request.form['username']
user.sex = request.form['sex']
# 接收多个值的用getlist()
user.mylike = '|'.join(request.form.getlist('like'))
user.city = request.form['city']
user.intro = request.form['intro']
db.session.commit()
return render_template("/user/edit_user.html", user=user)
Model.query.<查询条件>.<查询方法>
查询条件方法 | 说明 |
---|---|
filter() | 使用规则过滤 |
filter_by() | 比filter更方便使用 |
order_by() | 结果排序 |
limit(limit) | 只查询limit条 |
group_by() | 查询分组 |
offset() | 在原查询基础上偏移记录数,返回新的记录 |
filter()
方法使用
查询条件方法 | 说明 |
---|---|
filter(User.username==“luxp”) | 查找User中username值为luxp的用户 |
filter(User.age > 20) | 查找User中age值大于20的用户 |
filter(User.city != “010”) | 查找User中city值不为010的用户 |
filter(User.city.in_([‘010’, ‘021’, ‘0512’]) | 查找User中city值在[‘010’, ‘021’, ‘0512’]中的用户 |
filter(~User.city.in_([‘010’, ‘021’, ‘0512’]) | 查找User中city值不在[‘010’, ‘021’, ‘0512’]中的用户 |
filter(User.mylike.like(’%钓鱼%’)) | 查找User中用户爱好中包含钓鱼的用户 |
filter(User.username == “luxp”, User.age > 20) | 用户名为luxp且age>20的用户(多个条件and) |
filter(条件1)|(条件2)) | 满足条件1或者条件2的用户 |
filter_by()
方法使用
查询条件方法 | 说明 |
---|---|
filter_by(username == “luxp”) | 查找username值为luxp的用户 |
filter_by(username == “luxp”, sex=1) | 查找username值为luxp且sex=1的用户 |
模版: 提供一个搜索表单
路由: 如果是post
提交一定要在路由中添加POST
方法
视图: 如果接受到POST
数据,那么就要检查用户提交的数据,生成检索条件。
实操:
将app.py
中的userList()函数修改为如下内容:
@app.route('/userlist', methods=['GET', 'POST'])
def userList():
if request.method == 'POST':
# 关键字查询条件
q = request.form['q']
condition = { request.form['field']: q }
if request.form['field'] == "realname":
condition = User.realname.like('%%%s%%' % q)
else:
condition = User.username.like('%%%s%%' % q)
if request.form['order'] == '1':
# 升序
order = User.id.asc()
else:
# 降序
order = User.id.desc()
users = User.query.filter(condition, User.sex==request.form['sex']).order_by(order).all()
else:
users = User.query.all()
return render_template('user/user_list.html', users=users)
如果记录数很多,一页显示不完就需要分页显示
result = Model.query.<查询条件>.paginate(pageIndex, pageSize)
result
包含下列信息:
属性/方法 | 说明 |
---|---|
items | 当前查询的记录 |
page | 当前页数,即pageIndex |
per_page | 每页显示多少条记录即pageSize |
pages | 总页数 |
total | 记录总数量 |
next_num | 下一页 |
prev_num | 上一页 |
iter_pages | 生成翻页页码 |
prev() | 前一页对象 |
next() | 后一页对象 |
将app.py
中的userList()视图函数修改为如下内容:
#获取用户列表
@app.route('/userlist', methods=['GET', 'POST'])
def userList():
if request.method == 'POST':
# 关键字查询条件
q = request.form['q']
condition = { request.form['field']: q }
if request.form['field'] == "realname":
condition = User.realname.like('%%%s%%' % q)
else:
condition = User.username.like('%%%s%%' % q)
if request.form['order'] == '1':
# 升序
order = User.id.asc()
else:
# 降序
order = User.id.desc()
users = User.query.filter(condition, User.sex==request.form['sex']).order_by(order).all()
else:
# users = User.query.all()
page = request.args.get('page')
users = User.query.paginate(int(page), 10)
return render_template('user/user_list.html', users=users.items,
pages = users.pages,
total = users.total,
pageList = users.iter_pages()
)
filter()
和filter_by()
。filter()
功能强大,但是规则麻烦。filter_by()
用起来简单,但是能力稍微小一点。