从零开始用 Flask 搭建一个网站(二)
从零开始用 Flask 搭建一个网站(一) 介绍了如何搭建 Python 环境,以及 Flask 应用基本项目结构。我们要搭建的网站是管理第三方集成的控制台,类似于 Slack。 本篇主要讲解数据如何在 Flask 应用中流动,其它的框架基本上也是大同小异。
数据库
既然是数据的流动,首先要建立起存取数据的地方,也就是数据库了(这里是指关系型数据库,NoSQL 不在这讨论)。第一节中我们使用了 Flask-SQLAlchemy 管理数据库,在 Flask-SQLAlchemy 中,数据库使用 URL 指定,最流行的数据库 URL 格式如下:
数据库引擎 | URL |
---|---|
MySQL | mysql://username:password@hostname/database |
Postgres | postgresql://username:password@hostname/database |
SQLite(Unix) | sqlite:absolute/path/to/database |
SQLite(Windows) | sqlite:///c:/absolute/path/to/database |
在 config.py 中我们已经指定了数据库 URL,如果使用云平台部署程序,直接将生成的数据库 URL 写到 config.py 中 SQLALCHEMY_DATABASE_URI 即可。这里我们使用的是 SQLite 数据库。Flask-SQLAlchemy 采用数据库抽象层来操作数据库,也称为对象关系映射(Object-Relational Mapper, ORM),在用户不知不觉的情况下把高层的面向对象操作转换成低层的数据库指令,因此易用性好。我们已经在 app/__init__.py 中实例化了 SQLAlchemy 类:
app/__init__.py
from flask_sqlalchemy import SQLAlchemy
...
db = SQLAlchemy()
...
定义模型
模型类可以理解为数据库中的一张表,Flask-SQLAlchemy 提供了一个基类和一系列辅助类和函数来让我们定义模型的结构。我们直接在 app 文件夹下创建一个 models.py 文件。鉴于每个网站需求都不一样,所存的数据也不同,但本质上是大同小异的。这里以笔者网站需求为例,需要创建 Developer,Integration 和 Channel 三个表。
app/models.py 部分代码
from flask import current_app
from app import dbclass Developer(db.Model): __tablename__ = 'developers' id = db.Column(db.Integer, primary_key=True) dev_key = db.Column(db.String(40), unique=True, index=True) platform = db.Column(db.String(50)) platform_id = db.Column(db.String(40), unique=True) username = db.Column(db.String(150), index=True) integrations = db.relationship('Integration', backref='developer') channels = db.relationship('Channel', backref='developer')class Integration(db.Model): __tablename__ = 'integrations' id = db.Column(db.Integer, primary_key=True) integration_id = db.Column(db.String(40), unique=True) name = db.Column(db.String(100)) description = db.Column(db.String(150)) icon = db.Column(db.String(150)) channel = db.Column(db.String(150)) token = db.Column(db.String(150)) developer_id = db.Column(db.Integer, db.ForeignKey('developers.id'))class Channel(db.Model): __tablename__ = 'channels' id = db.Column(db.Integer, primary_key=True) developer_id = db.Column(db.Integer, db.ForeignKey('developers.id')) channel = db.Column(db.String(150)) def __repr__(self): return '<Channel %r>' % self.channel
上面的每个 Class 都继承了 Model 类,因此每个类在数据库中都体现为一张表,表名用 __tablename__ 表示,一般用复数形式。这里主要讲一下一对多的关系。可以看到上面 Developer 和 Integration 及 Channel 都有一个一对多的关系,一个用户可以有多个集成及多个频道。 看到这两句:
integrations = db.relationship('Integration', backref='developer')
developer_id = db.Column(db.Integer, db.ForeignKey('developers.id'))
第一句表明添加到 Developer 表的 integrations 属性表示这个关系的面向对象视角,对于一个 Developer 实例,integrations 属性将返回与 Developer 相关的所有 Integration,db.relationship() 第一个参数表明关系的另一端是哪个模型,backref 参数向 Integration 添加一个 developer 属性,从而定义反向关系。第二句是在 Integration 表中创建一个 developer_id 字段,这个字段被定义为外键,就是这个外键建立起了关系。传给 db.ForeignKey() 的参数 'developers.id' 表明这列的值是 developers 表中行的 id 值。另外,__repr__() 方法返回一个具有可读性的字符串表示模型,可以在调试和测试时使用。下面我们就在命令行中操作一下数据库。
首先执行:
//创建 migrations 文件夹及相关文件
python manage.py db init
然后执行 :
//自动创建迁移脚本
python manage.py db migrate
//创建数据表或者升级到最新版本
python manage.py db upgrade
以后模型类有改动,比如删除或添加列,都要执行这两个命令,更新数据库表。现在在项目目录下应该自动生成了名为 dev 的数据库。
接下来执行如下命令进入 Python Shell:
python manage.py shell
创建表
使用 db.create_all() 就可以根据模型类创建表。如图:
使用 db.drop_all() 方法就可以删除所有的表,但是这种方式比较粗暴,所有的数据也一同销毁了。
插入行
以下命令在数据库表中插入了一条数据:
通过数据库会话 db.session 来管理对数据库所做的改动,在准备把对象写入数据库之前,首先要添加到会话中,然后用 commit() 方法提交会话。接下来我们继续插入一条 Integration 数据:
>>>from app.models import Integration,Channel
>>>integration = Integration(integration_id='i0001',name='github',description='first >>>application',channel='github_event',developer=developer)
>>> db.session.add(integration)
>>> db.session.commit()
注意上面的 developer 属性,正是我们在 models.py 中 Developer 模型中定义的一对多关系 integrations 属性的 backref 值, 所谓的反向关系即指在 Integration 表中每条数据都有一个 developer 属性指向 Developer 表中的某条数据,这是一对多关系的高级表示。现在可以用 developer.integrations 来查看该 developer 拥有的哪些集成,运行截图如下:
修改行
在提交数据库会话之前,改变对象的某个属性然后再提交即可更新行数据。如:
>>> developer.username = 'lisi'
>>> db.session.add(developer)
>>> db.session.commit()
运行截图:
删除行
调用 db.session.delete() 方法即可删除行:
>>>db.session.delete(developer)
>>>db.session.commit()
查询行
Flask-SQLAlchemy 为每个模型提供了 query 对象,最基本的查询是返回表中的所有记录:
>>>Developer.query.all()
使用过滤器可以进行更精确的查询:
>>>Developer.query.filter_by(platform='qq').all()
如果你退出了 shell 会话,前面创建的对象就不会以 Python 对象的形式存在,而是作为各自数据库表中的行。这时需要重数据库中读取行,再重新创建 Python 对象,如:
>>> new_developer = Developer.query.filter_by(dev_key=12345).first()
注意上面的 first() 方法,如果不加上,将返回一个 BaseQuery 对象,这样就不能直接用 new_developer 来访问它的属性值。
在视图函数中操作数据库
上面介绍的所有数据库操作可以直接在视图函数中进行。假设我们要做一个简陋的注册功能,下面我们就来看看如何从网页中获取数据并保存在数据库中。我们先定义一个用户模型:
app/models.py
class User(db.model):__tablename__ = 'users'id = db.column(db.Integer, primary_key=True)username = db.column(db.String(50), unique=True)password = db.column(db.String(100))def __repr__(self):return '<User %r>' % self.username
然后在 main 文件夹下创建一个 forms.py 文件。
app/main/forms.py
from flask_wtf import Form
from wtforms import StringField, SubmitField, PasswordField
from wtforms.validators import DataRequiredclass UserForm(Form): username = StringField('Input your username', validators=[DataRequired()]) password = PasswordField('Input your password', validators=[DataRequired()]) submit = SubmitField('Submit')
我们使用了 flask-wtf 扩展(pip install flask-wtf)来处理表单。
然后我们用在 index 页面中显示这个表单。
index.html
{% extends "bootstrap/base.html" %}
{% import "bootstrap/wtf.html" as wtf %}{% block title %}注册{% endblock %}{% block content %}{% for message in get_flashed_messages() %} <div class="alert alert-warning"> <button type="button" class="close" data-dismiss="alert">×</button> {{ message }} </div>{% endfor %}<div id="form"><div class="col-md-4">{{ wtf.quick_form(form) }}</div></div>
{% endblock %}
现在回到 views.py 中,在我们的视图函数中作如下改动:
app/main/views.py
...
from .forms import UserForm
from ..models import User
from app import db@main.route('/', methods=['GET', 'POST'])
def signin():form = UserForm()if form is None:flash('Should input username and password')elif form.validate_on_submit():user = User(username=form.username.data, password=form.password.data)db.session.add(user)try:db.session.commit()flash('User created !')except:db.session.rollback()flash('User create failed')return render_template('index.html', form=form)
接下来我们运行一下这个小试验:
python manage.py runserver
总结
本节我们介绍了在 Flask 中是如何使用 Flask-SQLAlchemy 、Flask-Migrate来管理数据库,并且示范了数据从网页储存到数据库的过程,这只是最基础的部分,下一节我们将探索如何在网页上发送请求并且得到数据,以及如何在页面之间传递数据。
作者:KenChoi - 极光
原文:从零开始用 Flask 搭建一个网站(二)
知乎专栏:极光日报
转载于:https://www.cnblogs.com/jpush88/p/6697806.html
从零开始用 Flask 搭建一个网站(二)相关推荐
- 如何从零开始搭建一个网站
如何搭建一个网站,我估计很多程序员都有这个冲动想去搭建一个属于自己的网络小天地,但是苦于不知道从何下手,或者因为不知道水有多深,而望而却步,其实搭建网站没有你想的那么复杂,且听我细细分解, 一共就五步 ...
- python云服务器搭建教程_Python利用flask搭建一个共享服务器的步骤
这篇文章我们来讲一下在网站建设中,Python利用flask搭建一个共享服务器的步骤.本文对大家进行网站开发设计工作或者学习都有一定帮助,下面让我们进入正文. 零.概述 我利用flask搭建了一个简易 ...
- windows和Linux利用Python快速搭建一个网站
windows和Linux利用Python快速搭建一个网站 一.windows 步骤1:安装Python3(自行百度) 步骤2:在cmd窗口输入ipconfig查看本机ip地址,IPV4那一行.如:1 ...
- scrapy爬取表情包使用flask搭建搜索网站
本文以doutula为演示站点,详细说明搭建一个自己的表情包搜索网站的过程.主要步骤如下: 1. scrapy爬取表情包并存入mysql 2. flask搭建搜索网站 准备工作,anaconda py ...
- python打造流媒体服务器_使用Flask搭建一个流媒体服务器
摘要 收到前不久订阅的PythonWeekly发过来的一个邮件通知,由Miguel写的一篇介绍如何使用Flask搭建一个流媒体服务器的文章,思路很新颖也很有意思.你可以点击这里阅读英文原文.或者跟随本 ...
- 使用Flask搭建一个流媒体服务器
摘要 收到前不久订阅的PythonWeekly发过来的一个邮件通知,由Miguel写的一篇介绍如何使用Flask搭建一个流媒体服务器的文章,思路很新颖也很有意思.你可以点击这里阅读英文原文.或者跟随本 ...
- 怎样获取网站的域名_搭建一个网站,通常的6大步骤你知道吗?
怎样建网站?要搭建一个网站,通常有6个步骤.下面我们简单的介绍如何一步一步搭建网站. 第一步:注册域名 挑选网站地址,注册专属域名.注册域名的价格取决于具体用什么样的后缀域名搭建网站.目前可以选择的域 ...
- php平台cdn搭建,PHP 搭建一个网站配置CDN产品?
PHP 搭建一个网站配置CDN产品?留意存留或个人收藏自然环境配备的文本文档,开发工具升级搞好备份数据.团结协作篇:应用团结协作专用工具如 GITHUB ,优良的版本控制和工作流引擎会降低矛盾的成本, ...
- 搭建一个网站需要哪些东西?
了解干货不迷路,现在给大家分享一下搭建一个网站需要哪些东西?希望对大家有所帮助. 现在互联网很发达,网站对企业的重要性也是有目共睹的,因为网站就相当于企业的门户,企业的名片,是必不可少的互联网工具之一 ...
最新文章
- 缩小门店、打造智慧供应链,沃尔玛准备这样迎接新零售时代
- eclipse启动maven项目报类找不到
- Java 技术篇-使用poi开源jar包实现读取excel实例演示,poi-3.17.jar获取
- windows下架构svn服务器
- MongoDB常用操作命令
- 网关Spring Cloud Gateway科普
- 同时买票是怎么实现的_去巴黎玩怎么买地铁票最划算?| 巴黎最全交通攻略
- lua __index __newindex upvalue 示例
- kubernetes中port、target port、node port的对比分析,以及kube-proxy代理
- Ubuntu 16.04安装PPA图形化管理工具Y PPA Manager
- python 读png的值变了_深度学习数据预处理_python批量转换labelme标注的json格式标签为png格式...
- 大数据开发离线计算框架知识点总结
- mysql sql 分析工具下载_DB Query Analyzer下载
- 微信号下方菜单如何设置
- 水果电商“异军突起”,资本市场为何竞相追捧?
- 初一数学绩差,需要补习初一数学吗?
- 教你去掉 U盘写保护
- 数据分析真题日刷 | 网易2018校招数据分析师笔试卷
- linux怎么运行quartus,如何安裝Linux版本的Quartus II
- 哈夫曼树:HDU5884-Sort(队列、哈夫曼树)