Flask07——数据库操作-增删改查作者

从黑窗口操作数据库到网页操作数据库

终于到了我们要操作数据库的时候了,接下来的学习将会让你更有成就感,学完了基础的枯燥的语法,现在就到了我们去做一些功能的时候了,我们在网上看到的形形色色的网站从技术上来说其实可以包括两大块:代码实现业务逻辑,数据库保存真实的数据。两者有机的配合才得以形成了我们看到的各种网站。具体数据该怎么展示,这就是代码要做的事情了,这就是我们经常会用到的查询数据。另外,当然还有访问者与网站的交互,可能会添加新数据到网站,修改完整的信息,或者删除一些网站的内容。这些其实都是通过代码来调用数据库来实现最终的增删改查,而已经不是我们之前在黑窗口敲命令来实现增删改查了。网站的增删改查都是由各个请求激发的。那么代码如何操作数据库呢?当然有些同学可能用过由pymysql提供的操作数据库的方法,当然那只是由pymysql包在了我们原生mysql语句的外面,实际上你写的还是原生的sql语句,只是换到了代码里面。那么今天我们讲的操作数据库的方法就要颠覆之前原生语句的实现方式,而是采用我们Python中的类实例化对象,调用对象中的各种方法来操作数据库。

ORM对象关系映射

试想一下,如果我们可以这样定义一个类,比如我们定义一个user类,接着再给user类定义一些属性,比如id、name。然后我们还可以像定义数据库字段一样的来定义id为整型,主键,且可以自动增长。name为字符串,默认不能为空。然后我们可以通过某个指令直接在某个数据库test1中新建一张数据表user。这样我们就通过代码的类新建了数据库的一张表。表建好了,那么随之而来的自然就是要操作表了。当然我们也不会像以前那样写原生的sql语句,我们还可以实例化一下user类,然后用实例化后的user对象,调用类下面的方法比如:user.save(),user.find(),user.edit(),user.delete()来直接操作数据库。做我们的增删改查。是不是特别方便呢?当然上面是伪代码,不是真实的语法。答案是肯定的,这就是我们下面要讲的orm技术,全称为object relation mapping:对象关系映射。通俗来讲就是我们要用对象的形式来解决数据的关联关系问题,也就是把由数据库做的事情挪到了代码层。

flask_sqlalchemy扩展的安装和配置

而在我们的flask框架中,是通过一个扩展来实现的:flask_sqlalchemy。
要使用这个扩展首先需要安装一下:pip install flask_sqlalchemy ,另外要调用mysql我们还需要安装一个mysql的驱动:pip install pymysql。安装了这两个包之后我们就可以首先进行一些链接数据库的配置了。链接数据库的配置项我们可以写在配置文件当中。配置项如下:

SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:@127.0.0.1:3306/test1?charset=utf8'

等号前面的配置项名称是固定的,必须这样写才能被框架正确识别,等号后面的含义:链接的数据库类型+使用的驱动://用户名:密码@数据库地址:端口/数据库名称?数据库编码。接着我们还可以再配置一项内容:SQLALCHEMY_ECHO=True。这个配置项的含义是要把我们操作数据库的语句打印到控制台。
配置完之后,接下来我们就需要用flask_sqlalchemy来实例化出来我们的db对象了,并且要绑定到我们的app上面,代码如下:

from flask_sqlalchemy import SQLAlchemy  # 导入扩展包

app = Flask(__name__)

app.config.from_object('setting')  # 引入数据库配置项

db = SQLAlchemy(app=app)  # 实例化SQLAlchemy类,并绑定到app上

经过上面之后,我们才能在flask框架中使用由flask_sqlalchemy扩展提供的各种操作。

创建表

下面我们用flask_sqlalchemy提供的建表语句来通过类的形式创建表。

class Author(db.Model):
    id = db.Column(db.Integer, primary_key=True, comment='作者主键ID')
    name = db.Column(db.String(30), nullable=False, comment='作者姓名')

下面说一下上面的建表语句的注意点。首先要想使得我们创建的这个类能跟数据库的表产生映射关系,首先很重要的一点就在于要让我们这个类继承自db.Model类,然后表中的每个字段都是通过db.Column来创建的,里面的参数既是这个字段的约束。

db.Integer:定义此字段为整型
primary_key:定义此字段为主键且自动递增
comment:定义此字段注释
db.String(30):定义此字段为字符串,括号内定义字符串长度
nullable:定义此字段是否为空,False即不为空

上面就是关于类定义数据库表的具体解释。那么我们怎么来创建表呢?

创建表

可以通过在在main的判断条件的地方加建表语句db.create(),一般为了避免数据冗余会在创建之前先清空一下数据库,会加上db.drop(),来删除之前存在的所有数据。具体如下:

if __name__ == '__main__':
    db.drop_all()
    db.create_all()
    app.run(port=9000)

然后重启服务,如果你配置正确,这个时候你会在控制台看到打印出来的建表语句,能打印出来就是我们刚才配置的SQLALCHEMY_ECHO=True在起作用。然后我们可以用可视化工具navicat查看一下我们是否成功创建了表呢。创建之后就可以把db.drop_all()和db.create_all()给注释掉,不然等下我们写入数据的话,会把我们的数据给清除掉。需要使用的时候再打开。

模板

<!--base.html文件-->
{% block top %}
    <a href="{{ url_for('index') }}">首页</a>
    <a href="{{ url_for('all_authors') }}">所有作者</a>
    <a href="{{ url_for('add_author') }}">添加作者</a>
    <hr>
{% endblock top %}
{% block content %}
    内容
{% endblock content %}
{% block bottom %}
    <hr>
    底部
{% endblock bottom %}
<!--index.html文件-->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
    {% extends 'base.html' %}
    {% block content %}
        首页
    {% endblock content %}
</body>
</html>

添加作者

@app.route('/')
def index():
    return render_template('index.html')
    
@app.route('/add_author', methods=['GET', 'POST'])
def add_author():
    if request.method == 'POST':  # 接收数据和提交到数据库都是用的post请求
        name = request.form.get('name')  # 接收要添加的数据,通过参数名获取传递的内容
        new_author = Author(name=name)  # 实例化Author类生成一个新对象,对应数据库里面的一条新的记录
        # 有错误立即显示出来。
        # db.session.add(new_author1)  # 做添加的准备
        # db.session.commit()  # 真正的提交
        # try except可以将错误捕获隐藏,自己自定义错误提醒。
        try:
            db.session.add(new_author1)  # 做添加的准备
            db.session.commit()  # 真正的提交
            flash('添加成功!')
        except Exception as e:
            flash('添加不成功!')
    return render_template('add_author.html')  # 展示模板页面是用的get请求
<!--add_author.html文件-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>添加作者</title>
</head>
<body>
    {% extends 'base.html' %}
    {% block content %}
        <form action="" method="post">
            作者名称:<input type="text" name="name" value="" > <br>
            <input type="submit" value="确认添加">
        </form>
        {% for message in get_flashed_messages() %}
            <span style="color:red">{{ message }}</span>
        {% endfor %}
    {% endblock content %}
</body>
</html>

所有作者

@app.route('/all_authors')
def all_authors():
    authors = Author.query.all()  # 通过此方法可以获取作者表所有作者记录
    print(authors)
    return render_template('all_authors.html', authors=authors)  # 传递给模板,来遍历所有作者记录
<!--all_authors.html-->

<!DOCTYPE html>
<html lang="en">
<head><!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>所有作者</title>
</head>
<body>
    {% extends 'base.html' %}
    {% block content %}
        {% for author in authors %}
            <p>{{ author.id }}、{{ author.name }} |
                <a href="{{ url_for('edit_author', author_id=author.id) }}">编辑</a> |
                <a href="{{ url_for('delete_author', author_id=author.id) }}">删除</a> |
            </p>
        {% endfor %}
        {% for message in get_flashed_messages() %}
            <span style="color:red">{{ message }}</span>
        {% endfor %}
    {% endblock content %}
</body>
</html>

编辑作者

# 和添加不同的是需要传递修改数据的id,才知道你要修改哪条数据
@app.route('/edit_author', methods=['GET', 'POST'])
def edit_author():
    author_id = request.args.get('author_id')  # 确定拿到要修改哪条记录的id
    one_author = Author.query.get(author_id)  # 根据当前数据的id,通过主键到数据库拿到当前id的记录(对象)
    if request.method == 'POST':
        name = request.form.get('name')  # 需要修改的数据
        one_author.name = name  # 将传递过来的name的值赋值到现有对象(记录)的相应字段name上
        try:
            db.session.add(one_author)
            db.session.commit()
            flash('修改成功!')
        except Exception as e:
            flash('修改不成功!')
        return redirect(url_for('all_authors'))
    return render_template('edit_author.html', one_author=one_author)  # 传递作者现有数据到模板,以备显示出来
<!--edit_author.html-->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>编辑作者</title>
</head>
<body>
    <form action="" method="post">
        <input type="text" value="{{ one_author.name }}" name="name">
        <input type="submit" value="确定编辑">
    </form>
</body>
</html>

删除作者

@app.route('/delete_author')
def delete_author():
    author_id = request.args.get('author_id')  # 跟编辑一样需要获取当前用户的id
    one_author = Author.query.get(author_id)  # 通过id获取当前记录(对象)
    try:
        db.session.delete(one_author)  # 删除整条记录(对象)
        db.session.commit()
        flash('删除成功!')
    except Exception as e:
        flash('删除不成功!')
    return redirect(url_for('all_authors'))  # 删除之后跳转到所有作者页面
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值