4.3 数据库

——————————————————————前言————————————————————————————

本节讲解使用flask-sqlalchemy扩展管理数据库。

————————————————————————————————————————————————————


一. 安装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 os

from flask_sqlalchemy import SQLAlchemy

basedir = os.path.abspath(os.path.dirname(__file__))  #hello.py脚本文件所处目录

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'sqlite.data')  #设置数据库url

app.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'))  #返回响应
四. 修改模板index.html
{% extends 'base.html' %}

{% import 'bootstrap/wtf.html' as wtf %}

{% block title %}Flasky{% endblock %}

{% block page_content %}

<div class='page-header'>

<h1>Hello, {% if name %} {{ name }} {% else %} Stranger{% endif %} !</h1>

{% if not known %}

<p>nice to meet you!</p>

{% else %}

<p>happy to meet you again!</p>

{% endif%}

</div>

{{ wtf.quick_form(form) }}

{% endblock %}

五. 效果展示

地址栏输入根地址并回车


文本框输入Dave并点击提交按钮

上步操作后数据库的变化, 多了一个名为Dave的用户

再次输入Dave时浏览器界面的变化


以上几步效果展示可以结合视图函数来分析。






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值