Python学习笔记:6.2.3 增删改查CURD

前言:本文是学习网易微专业的《python全栈工程师 - Flask高级建站》课程的笔记,欢迎学习交流。同时感谢老师们的精彩传授!

一、课程目标

  • 用户列表
  • 用户信息删除与修改
  • 用户条件查询
  • 页面跳转

二、详情解读

2.1.C - create创建
2.1.1.数据创建
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()

Python学习笔记:6.2.3 增删改查CURD_第1张图片
Step3.新开一个命令行窗口,在虚拟环境中运行下面命令,打开sqlite数据库的web界面:

sqlite_web my.db

Python学习笔记:6.2.3 增删改查CURD_第2张图片
通过打开的网页窗口,我们可以看到新增虚拟用户(我这里是运行了两次,加注册了一个,所以一共是201个数据)
Python学习笔记:6.2.3 增删改查CURD_第3张图片

2.2.R - read读取数据记录
2.2.1.读取操作

查询通过模型类的query对象方法:Model.query.<查询方法>

查询方法 说明
all() 获得所有记录
first() 获得第一条记录,找不到返回None
one() 返回唯一 一 条记录,如果存在多条或者没有则报错
get(id) 传入主键id,返回与主键值匹配的记录,无匹配返回None
count() 返回查询结果总数
one_or_none 与one()一样,如果结果不唯一,返回None
2.2.2.模版与视图准备

模版:需要提供一个用户列表显示模版
路由:提供一个访问路径。比如:@app.route("/userlist")
视图函数:通过模型对象查询结果,并将结果赋给模版变量

新建文件:templates/user/edit_user.htmltemplates/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)
2.3.D - delete删除记录
2.3.1.删除记录

(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中新增如下视图函数,记得在文件前面引入redirecturl_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'))
2.4.U - update更新记录
2.4.1.更新操作

(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)
2.5.条件检索

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)
2.6.分页显示

如果记录数很多,一页显示不完就需要分页显示
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()
                           )

三、课程小结

  • CURD
  • 条件检索
    条件检索主要是filter()filter_by()filter()功能强大,但是规则麻烦。filter_by()用起来简单,但是能力稍微小一点。
  • 翻页
    在数据量很多的情况下,需要使用翻页,将数据分成几部分显示,否则一下子选择很多,会增加数据库、程序和网络的负担。

你可能感兴趣的:(Python全栈工程师学习笔记,flask数据库操作,sqlalchemy查询)