从零开始用 Flask 搭建一个网站(二)

news/2024/4/27 16:19:43/文章来源:https://blog.csdn.net/weixin_33966095/article/details/89050650

从零开始用 Flask 搭建一个网站(一) 介绍了如何搭建 Python 环境,以及 Flask 应用基本项目结构。我们要搭建的网站是管理第三方集成的控制台,类似于 Slack。 本篇主要讲解数据如何在 Flask 应用中流动,其它的框架基本上也是大同小异。

数据库

既然是数据的流动,首先要建立起存取数据的地方,也就是数据库了(这里是指关系型数据库,NoSQL 不在这讨论)。第一节中我们使用了 Flask-SQLAlchemy 管理数据库,在 Flask-SQLAlchemy 中,数据库使用 URL 指定,最流行的数据库 URL 格式如下:

clipboard.png

在 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() 就可以根据模型类创建表。如图:

clipboard.png

使用 db.drop_all() 方法就可以删除所有的表,但是这种方式比较粗暴,所有的数据也一同销毁了。

插入行

以下命令在数据库表中插入了一条数据:

clipboard.png

通过数据库会话 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 拥有的哪些集成,运行截图如下:

clipboard.png

修改行

在提交数据库会话之前,改变对象的某个属性然后再提交即可更新行数据。如:

>>> developer.username = 'lisi'
>>> db.session.add(developer)
>>> db.session.commit()

运行截图:

clipboard.png

删除行

调用 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来管理数据库,并且示范了数据从网页储存到数据库的过程,这只是最基础的部分,下一节我们将探索如何在网页上发送请求并且得到数据,以及如何在页面之间传递数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_769841.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网站平台架构演变史(三) - 数据库表的查询优化

上篇说道了数据库读写分离&#xff0c;对于大型网站来说这么说是十分有必要的。数据库在整个互联网架构中担当的角色无法有两个&#xff0c;存储和运算&#xff0c;很多时候这两个是并存的&#xff0c;但是在后期&#xff0c;对于上亿条数据来说&#xff0c;让数据库既要存储&a…

教你如何安装配置Windows7系统 IIS IIS7.5本地浏览测试网站 完整版介绍

大家都知道网站建设前期测试于浏览网站都喜欢用iis本地浏览来操作 那么为了方便大家自己来安装和配置Internet信息服务 相信大家&#xff0c;对于Windows 7有了相应的了解&#xff0c;从操作上&#xff0c;使用上&#xff0c;内置功能上都有了一定的认识。Windows 7对于广大朋友…

网站静态化处理—web前端优化—中(12)

Web前端很多优化原则都是从如何提升网络通讯效率的角度提出的&#xff0c;但是这些原则使用的时候还是有很多陷阱在里面&#xff0c;如果我们不能深入理解这些优化原则背后所隐藏的技术原理&#xff0c;很有可能掉进这些陷阱里&#xff0c;最终没有达到最佳的预期效果&#xff…

iphone/ipad网站开发技巧归纳

为什么80%的码农都做不了架构师&#xff1f;>>> iphone/ipad最近凶得很&#xff0c;自己也玩上了iphone和ipad&#xff0c;在此把收集到的一些开发技巧罗列出来,方便项目中参考使用,如下&#xff1a;侦测iPhone/iPod&#xff1b;开发特定设备的移动网站&#xff0c…

Anonymous攻击世贸组织网站 内部人员信息泄露

黑客组织匿名者近日入侵了世界贸易组织(WTO)的网站并泄露了大量成员的个人信息。 匿名者又来了 最近&#xff0c;匿名者成员大肆入侵了WTO的数据库、攻击以色列武器经销进口商并在#OpIsrael计划中泄露大量在线客户端登录的数据。 据统计&#xff0c;此次的入侵WTO事件波及到来自…

如何订阅没有RSS输出的网站

1、利用Google资讯 也许国内使用Google资讯的人并不多&#xff0c;Google 资讯是一个由计算机生成的资讯网站。它汇集了来自中国大陆超过1,000 个中文资讯来源的新闻资源&#xff0c;并将相似的报道组合在一起&#xff0c;根据读者的个人喜好进行显示。 Google资讯支持RSS或Ato…

微软PDC大会直播实录,徐汇区网站设计

导读&#xff1a;来自MSDN China博客&#xff0c;作者是微软中国DPE部门的俞辉&#xff0c;从现场报道。 PDC10官方网上直播&#xff1a;http://www.microsoftpdc.com/?WT.mc_idaff-n-cn-loc-PDC-csdn 好多breakout session都非常好&#xff01; 会议开始之前&#xff0c;排队…

尝鲜Jumony for MVC,体验插件化网站开发

Jumony for MVC是这一年来Jumony项目的重头戏&#xff0c;Jumony for MVC是Jumony技术与ASP.NET MVC的结合&#xff0c;尽管现在Jumony for MVC还未发布稳定版本&#xff0c;但确实是非常值得一试的一个视图引擎。希望这篇文章能给大家带来眼前一亮的感觉。 在“用网站&#xf…

网站设计常用技巧收集(转)

原链接&#xff1a;http://www.cnblogs.com/sufei/archive/2011/11/30/2268709.html 先说一下写这篇文章的目的吧&#xff0c;这上面的东西很多不是我写的&#xff0c;也不是我总结的&#xff0c;这点我肯定&#xff0c;呵呵&#xff0c;我希望大家也能提提你自己的建议&#x…

easyui中文api网站

2019独角兽企业重金招聘Python工程师标准>>> http://easydoc.cloudfoundry.com/doc/easyui/1.2.5/ easyui中文api网站 转载于:https://my.oschina.net/meSpace/blog/51946

linux下网站平台的搭建——apache +PHP+mysql

linux下网站平台的搭建——apache PHPmysql实验环境 VMware 6.5.2redhat Enterprise 5 AS我的内核版本本文实验基础环境已经做好了一个dns的解析本文中的几个组件均为源码包安装 &#xff0c;介于可能有版本的不同安装略有差异本文大致可以分为以下步骤mysql的安装与简单配置ap…

一次设计高可用网站的实战经验

我公司前段时间做了一个活动&#xff0c;花了5000块购买了5台虚拟机(每台cpu 为单核2GHZ&#xff0c;内存为1.5GB)做了一个两个月大活动,我设计支持高并发的系统如下&#xff1a; 活动的特点是高并发&#xff0c;逻辑不是很复杂&#xff0c;因此我采用DNS做负载均衡器nginx做前…

网站的灰度发布

2019独角兽企业重金招聘Python工程师标准>>> 1、概述 在传统软件产品发布过程中&#xff08;例如微软的Windows 7的发布过程中&#xff09;&#xff0c;一般都会经历Pre-Alpha、Alpha、Beta、Release candidate&#xff08;RC&#xff09;、RTM、General availabil…

阿里云服务器:IIS网站的架设(一、环境设置与安装IIS网站 二、网站的基本设置 三、建立新网站(未完待续))...

Windows Server 2012 R2的Internet Information Services &#xff08;IIS&#xff09;网站的模块化设计&#xff0c;可以减少被攻击面并减轻管理负担&#xff0c;让系统管理员更容易架设安全的具备高扩展的网站。 欢迎关注github&#xff1a;https://github.com/saucxs 一、环…

只有搞Java开发的才知道!java相关技术网站

第一篇Linux基础学习篇 目录 第零章﹑计算机概论关于电脑的硬件组成部分﹐其实你可以观察你的台式机来分析一下﹐依外观来说这家伙主要可分为三部分﹐分别是∶ 输入单元∶包括键盘﹑鼠标﹑读卡机﹑扫描仪﹑手写板﹑触摸屏等等一堆﹔主机部分∶这个就是系统单元﹐被主机机箱保护…

MVC网站发布到 IIS

接下来将发布成功的站点部署到iis7.0。 步骤如下&#xff1a; 1. 安装 Microsoft .net FrameWork 4.0安装包&#xff08;网站开发时候使用的就是.net framework4.0框架&#xff09;; 2. 安装ASP.NET MVC 4.0 ; 3. 设置IIS的“ISAPI和CGI限制”中的“ASP.NET v4.0.0.30319”为允…

Slog42_支配vue框架初阶项目之博客网站-单页-默认头像的布局和定位

ArthurSlogSLog-42Year1GuangzhouChinaAug 19th 2018GitHub掘金主页简书主页segmentfault从业之路不同 机缘也不同 人生轨迹由机缘组成 想要有什么样的机缘 也就明白了自己要走的路 开发环境MacOS(High Sierra 10.13.5) 需要的信息和信息源&#xff1a; css 元素框的类型HTML D…

在电脑上测试手机网站全攻略

最近公司要开发网站的移动版&#xff0c;让我准备准备知识&#xff0c;话说本人开发移动网站的经验还真不多&#xff0c;最悲剧的事情就是我的手机是个经典的诺基亚&#xff0c;而且公司还不给配手机&#xff0c;这是有多扣啊&#xff0c;没办烦啦&#xff0c;没有手机就用电脑…

教资报名网站显示无法访问此页面

网上很多人解决办法是 把网址复制出来, 开头的https:// 换成 http:// 添加到浏览器的兼容性页面应该就能打开了 ,最终效果是可以的,但是治标不治本, 在选完笔试科目后 点击付款就会出现和之前相同的问题 2.最终解决办法如下 勾选为TLS 1.2, 1.1即可

常用工具网站

1. 在线PDF转Word免费的转换器工具 https://www.pdfkz.com/pdf-to-word 2. 在线图片免费拼接 https://www.toolnb.com/tools/tppj.html