day58-Flask模型深入

一、模型定义

1.安装flask_sqlalchemy和mysql驱动

pip install flask-sqlalchemy

pip install mysql

2.定义模型(models.py)

from flask_sqlalchemy import SQLAlchemy

# 获取SQLAlchemy对象
db = SQLAlchemy()


class Student(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    s_name = db.Column(db.String(80), unique=True, nullable=False)

    # 定义表名
    __tablename__ = 'stu'

二、数据库连接

1.配置数据库

app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@127.0.0.1:3306/flask'

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

2.初始化db和app对象

from flask_sqlalchemy import SQLALchemy

方法一:
app = Flask(__name__)

db = SQLAlchemy(app)

方法二:
from app.models import db

app = Flask(__name__)

db.init_app(app)

三、数据库迁移

1.创建数据表
db.create_all()表示创建定义模型中对应到数据库中的表

注意:db.create_all()只可以调用一次。

@blue.route('/create_db/')
def create_db():
    db.create_all()
    return '创建数据库成功'

2.删除数据库中所有的表
db.drop_all()表示删除数据库中所有的表

@blue.route('/drop_db/')
def drop_db():
    db.drop_all()
    return '删除数据库成功'

四、查询数据

1.语法

模型.query.all()

模型.query.filter(模型.属性名 == xxx)

模型.query.filter_by(属性名=xxx)

模型.query.get(id)

2.数据操作

db.session.add(object)

db.session.commit()

3.查询所有学生的信息
注意:all()返回的结果是列表。

@blue.route('/list/', methods=['GET'])
def stu_list():
    students = Student.query.all()

    return render_template('list.html', students=students)

4.排序
(1)升序
对象 = 模型.query.order_by(属性名)
对象 = 模型.query.order_by(属性名 asc)
(2)降序
对象 = 模型.query.order_by(-属性名)
对象 = 模型.query.order_by(属性名 desc)

@blue.route('/sel_stu/', methods=['GET'])
def sel_stu():
    # 升序
    stus = Student.query.order_by('s_age')
    stus = Student.query.order_by('s_age asc')

    # 降序
    stus = Student.query.order_by('-s_age')
    stus = Student.query.order_by('s_age desc')

    return '查询成功'

5.获取指定条数的数据
stus = 模型.query.offset(跳过的记录条数).limit(截取的记录条数)

@blue.route('/sel_stu/', methods=['GET'])
def sel_stu():
    stus = Student.query.offset(0).limit(2)

    return '查询成功'

6.模糊查询
contains():包含
startswith():以特定字符开头
endswith():以特定字符结尾
like():模糊查询

@blue.route('/sel_stu/', methods=['GET'])
def sel_stu():
    stus = Student.query.filter(Student.s_name.contains('小明')).all()

    stus = Student.query.filter(Student.s_name.startswith('小')).all()

    stus = Student.query.filter(Student.s_name.endswith('明')).all()

    stus = Student.query.filter(Student.s_name.like('_明%')).all()

    return '查询成功'

7._in查询

@blue.route('/sel_stu/', methods=['GET'])
def sel_stu():
     stus = Student.query.filter(Student.id.in_([1, 2, 3, 4, 5]))
    return '查询成功'

8.条件查询
lt: <
le: <=
gt: >
ge: >=

@blue.route('/sel_stu/', methods=['GET'])
def sel_stu():
    # 小于
    stus = Student.query.filter(Student.s_age.__lt__(21)).all()
    stus = Student.query.filter(Student.s_age < 21).all()

    # 小于等于
    stus = Student.query.filter(Student.s_age.__le__(21)).all()
    stus = Student.query.filter(Student.s_age <= 21).all()

    # 大于
    stus = Student.query.filter(Student.s_age.__gt__(21)).all()
    stus = Student.query.filter(Student.s_age > 21).all()

    # 大于等于
    stus = Student.query.filter(Student.s_age.__ge__(21)).all()
    stus = Student.query.filter(Student.s_age >= 21).all()

    return '查询成功'

9.条件查询
and_:与
or_:或
not_:非

@blue.route('/sel_stu/', methods=['GET'])
def sel_stu():
    # and_
    stus = Student.query.filter(and_(Student.s_age < 22, Student.s_name.endswith('明'))).all()
    stus = Student.query.filter(Student.s_age < 22).filter(Student.s_name.endswith('明')).all()
    stus = Student.query.filter(Student.s_age < 22, Student.s_name.endswith('明')).all()

    # or_
    stus = Student.query.filter(or_(Student.s_age < 22, Student.s_name.endswith('明'))).all()

    # not_
    stus = Student.query.filter(not_(Student.s_age == 22)).all()

    return '查询成功'

五、添加数据

提交事务,使用commit提交添加数据的操作
1.语法

对象 = 模型()
对象.属性名 = xxx

2.数据操作

db.session.add(对象)
db.session.commit

3.添加学生信息

@blue.route('/add/', methods=['GET', 'POST'])
def stu_add():
    if request.method == 'GET':
        return render_template('add.html')
    if request.method == 'POST':
        username = request.form.get('username')
        phone = request.form.get('phone')
        age = request.form.get('age')
        stu = Student()
        stu.s_name = username
        stu.s_phone = phone
        stu.s_age = age
        db.session.add(stu)
        db.session.commit()

        return redirect(url_for('app.stu_list'))

4.批量添加学生信息

@blue.route('/add_all/', methods=['GET'])
def add_all():
    stus = []
    for i in range(10):
        stu = Student()
        stu.s_name = '小明%s' % random.randint(0, 10000)
        stu.s_phone = '12345678910'
        stu.s_age = random.randint(18, 28)
        stus.append(stu)
    db.session.add_all(stus)
    db.session.commit()

    return '创建成功'

六、修改数据

1.语法

对象 = 模型.query.filter(模型.属性名 == xxx).first()

对象.属性名 = xxx

2.数据操作

db.session.commit()

3.修改学生信息
注意: db.session.add(stu)可以省略不写。

@blue.route('/edit/<int:id>', methods=['GET', 'POST'])
def stu_edit(id):
    if request.method == 'GET':
        stu = Student.query.filter(Student.id == id).first()
        return render_template('add.html', stu=stu)

    if request.method == 'POST':
        username = request.form.get('username')
        phone = request.form.get('phone')
        age = request.form.get('age')
        stu = Student.query.filter(Student.id == id).first()
        stu.s_name = username
        stu.s_phone = phone
        stu.s_age = age
        # db.session.add(stu)
        db.session.commit()

        return redirect(url_for('app.stu_list'))

七、删除数据

1.语法

对象 = 模型.query.filter(模型.属性名 == xxx).first()

2.数据操作

db.session.delete(对象)
db.session.commit()

3.删除指定id的学生

@blue.route('/del/<int:id>/', methods=['GET'])
def stu_del(id):
    if request.method == 'GET':
        # 1.获取删除的对象
        stu = Student.query.filter(Student.id == id).first()
        # 2.使用delete(对象)
        db.session.delete(stu)
        db.session.commit()

        return redirect(url_for('app.stu_list'))

八、分页

1.分页属性

分页对象.items:获取数据

分页对象.has_prev:是否存在上一页

分页对象.prev_num:上一页脚码

分页对象.has_next:是否存在下一页

分页对象.next_num:下一页脚码

分页对象.pages:共多少页

分页对象.page:当前页

分页对象.total:共多少条数据

分页对象.iter_pages():脚码

2.paginate实现分页

@blue.route('/list/', methods=['GET'])
def stu_list():
    page = int(request.args.get('page', 1))
    pre_page = 5
    paginate = Student.query.paginate(page, pre_page)
    students = paginate.items

    return render_template('list.html', students=students, paginate=paginate)

3.list.html

{% extends 'base.html' %}

{% block title %}
    学生列表页面
{% endblock %}

{% block content %}
    <p><a href="{{ url_for('app.stu_add') }}">添加学生信息</a></p>
    <table>
        <thead>
            <th>id</th>
            <th>姓名</th>
            <th>年龄</th>
            <th>电话</th>
            <th>操作</th>
        </thead>
        <tbody>
            {% for stu in students %}
            <tr>
                <td>{{ stu.id }}</td>
                <td>{{ stu.s_name }}</td>
                <td>{{ stu.s_age }}</td>
                <td>{{ stu.s_phone }}</td>
                <td>
                    <a href="{{ url_for('app.stu_edit', id=stu.id) }}">编辑</a>
                    |
                    <a href="{{ url_for('app.stu_del', id=stu.id) }}">删除</a>
                </td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
    <p>
        {% if paginate.has_prev %}
            <a href="{{ url_for('app.stu_list') }}?page={{ paginate.prev_num }}">上一页</a>
        {% endif %}

        {% for i in paginate.iter_pages() %}
            <a href="{{ url_for('app.stu_list') }}?page={{ i }}">{{ i }}</a>
        {% endfor %}

        {% if paginate.has_next %}
            <a href="{{ url_for('app.stu_list') }}?page={{ paginate.next_num }}">下一页</a>
        {% endif %}

        当前{{ paginate.page }}页,共{{ paginate.pages }}页,一共{{ paginate.total }}条数据
    </p>
{% endblock %}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341

推荐阅读更多精彩内容

  • 转 # https://www.cnblogs.com/easypass/archive/2010/12/ 08/...
    吕品㗊阅读 9,690评论 0 44
  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 31,872评论 2 89
  • 生命不在于活得长与短,只在于顿悟的迟与晚,从旅游的角度看人生一辈子是场旅行,短的是行程,长的是人生。生活要如流水般...
    风陌阅读 168评论 0 2
  • 参考文章 iTerm2官网 iTerm2、Bash和Zsh之间的区别是什么? 我在用的mac软件(1)--终端环境...
    刘大帅阅读 774评论 0 4
  • 在《平凡的世界》这本长篇小说中,我认为塑造得最成功也最饱满的一个人物形象便是孙少平,他热爱生活,从不在生活面前低头...
    当幸福砸中脑袋阅读 239评论 0 1