Flask从入门到精通之数据模型之间的关系
关系型数据库使用关系把不同表中的行联系起来。上篇随笔中介绍的用户和角色之间是一种简单的关系。即角色到用户的一对多关系,因为一个角色可属于多个用户,而每个用户都只能有一个角色。这种关系在模型中的表示方法如下:
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(),unique=True)
users = db.relationship('User', backref='role')
def __repr__(self):
return '<Role %r>' % self.name class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(),unique=True)
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
def __repr__(self):
return '<User %r>' % self.name
关系使用users 表中的外键连接了两行。添加到User 模型中的role_id 列被定义为外键,就是这个外键建立起了关系。传给db.ForeignKey() 的参数'roles.id' 表明,这列的值是roles 表中行的id 值。
添加到Role 模型中的users 属性代表这个关系的面向对象视角。对于一个Role 类的实例,其users 属性将返回与角色相关联的用户组成的列表。db.relationship() 的第一个参数表明这个关系的另一端是哪个模型。如果模型类尚未定义,可使用字符串形式指定。
db.relationship() 中的backref 参数向User 模型中添加一个role 属性,从而定义反向关系。这一属性可替代role_id 访问Role 模型,此时获取的是模型对象,而不是外键的值。
大多数情况下,db.relationship() 都能自行找到关系中的外键,但有时却无法决定把哪一列作为外键。例如,如果User 模型中有两个或以上的列定义为Role 模型的外键,SQLAlchemy 就不知道该使用哪列。如果无法决定外键,你就要为db.relationship() 提供额外参数,从而确定所用外键。下表列出了定义关系时常用的配置选项。
| backref | 在关系的另一个模型中添加反向引用 |
| primaryjoin | 明确指定两个模型之间使用的联结条件。只在模棱两可的关系中需要指定 |
| lazy | 指定如何加载相关记录。可选值有select(首次访问时按需加载)、immediate(源对象加载后就加载)、joined(加载记录,但使用联结)、subquery(立即加载,但使用子查询),noload(永不加载)和dynamic(不加载记录,但提供加载记录的查询) |
| uselist | 如果设为Fales,不使用列表,而使用标量值 |
| secondary | 指定多对多关系中关系表的名字 |
| secondaryjoin | SQLAlchemy 无法自行决定时,指定多对多关系中的二级联结条件 |
除了一对多之外,还有几种其他的关系类型。一对一关系可以用前面介绍的一对多关系表示,但调用db.relationship() 时要把uselist 设为False,把“多”变成“一”。多对一关系也可使用一对多表示,对调两个表即可,或者把外键和db.relationship() 都放在“多”这一侧。由于多对多关系比较复杂,后面会在专门的专题详细介绍。
Flask从入门到精通之数据模型之间的关系的更多相关文章
- Flask从入门到精通之使用Flask-Migrate实现数据库迁移
在开发程序的过程中,你会发现有时需要修改数据库模型,而且修改之后还需要更新数据库.仅当数据库表不存在时,Flask-SQLAlchemy 才会根据模型进行创建.因此,更新表的唯一方式就是先删除旧表,不 ...
- Flask从入门到精通之重定向和用户会话
最新版的hello.py 存在一个可用性问题.用户输入名字后提交表单,然后点击浏览器的刷新按钮,会看到一个莫名其妙的警告,要求在再次提交表单之前进行确认.之所以出现这种情况,是因为刷新页面时浏览器会重 ...
- Flask从入门到精通之Flask表单渲染成HTML
表单字段是可调用的,在模板中调用后会渲染成HTML.假设视图函数把一个NameForm 实例通过参数form 传入模板,在模板中可以生成一个简单的表单,如下所示: <form method=&q ...
- Flask从入门到精通之flask程序入门
初始化 所有Flask程序都必须创建一个程序实例,Web服务器使用一种名为Web服务器网关接口的的协议(WSGI),把接收自客户端的所有请求转发给这个对象处理.程序实例是Flask类的对象,使用下面代 ...
- Flask从入门到精通之大型程序的结构二
一.程序包 程序包用来保存程序的所有代码.模板和静态文件.我们可以把这个包直接称为app(应用),如果有需求,也可使用一个程序专用名字.templates 和static 文件夹是程序包的一部分,因此 ...
- Flask从入门到精通之大型程序的结构一
尽管在单一脚本中编写小型Web 程序很方便,但这种方法并不能广泛使用.程序变复杂后,使用单个大型源码文件会导致很多问题.不同于大多数其他的Web 框架,Flask 并不强制要求大型项目使用特定的组织方 ...
- Flask从入门到精通之使用Flask-SQLAlchemy管理数据库
Flask-SQLAlchemy 是一个Flask 扩展,简化了在Flask 程序中使用SQLAlchemy 的操作.SQLAlchemy 是一个很强大的关系型数据库框架,支持多种数据库后台.SQLA ...
- Flask从入门到精通之Flash消息
请求完成后,有时需要让用户知道状态发生了变化.这里可以使用确认消息.警告或者错误提醒.一个典型例子是,用户提交了有一项错误的登录表单后,服务器发回的响应重新渲染了登录表单,并在表单上面显示一个消息,提 ...
- Flask从入门到精通之在视图函数中处理表单
在新版hello.py 中,视图函数index() 不仅要渲染表单,还要接收表单中的数据.更新后的index() 视图函数如下: @app.route('/') def index(): name = ...
随机推荐
- laravel的foreach
1.控制器 2.模板
- C++对象拾遗
#include <iostream.h> #include <string.h> //using namespace std; class A { public: A ...
- jQuery 插件使用记录
Validate 表单验证 ver 1.6 浏览更多 默认情况下,当表单 submit 时,那些验证不通过的 field 旁边会出现错误消息提示,有时很方便,但有时看起来很不美观.可以关闭此消息提示. ...
- jQuery nyroModal 插件遇到问题
nyroModal ver 1.6.2 弹出层插件 浏览更多 初始化大小问题 //页面加载完成后初始化 设置大小 $(function() { $.nyroModalSettings({ widt ...
- KBMMW 4.6 正式版发布
喜大普奔迎新年! Merry Christmas! We are happy to announce the release of kbmMW v. 4.60.00 Professional and ...
- 一个 图片 滚动 飞入的css特效
@keyframes bounceInLeft { from, 60%, 75%, 90%, to {animation-timing-function: cubic-bezier(0.215, 0. ...
- 如何在eclipse的配置文件里指定jdk路径
转载自:https://blog.csdn.net/gnail_oug/article/details/51925804:个人做了些小修改. 今天下载了eclipse4.6版本,打开时报Version ...
- Android在layout xml中使用include[转]
在Android的layout样式定义中,可以使用xml文件方便的实现,有时候为了模块的复用,使用include标签可以达到此目的.例如: <include layout="@layo ...
- Windows10+Python3下安装NumPy+SciPy+Matplotlib
Numpy.SciPy.MatplotLib是Python下从事科学计算必不可少的库.我在用其他的方法安装时出现各种问题,发现直接安装.whl包是最快且不报错的方法. 1.下载.whl包在下面的网站中 ...
- (动态规划 01背包 打印路径) CD --UVA --624
链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87813#problem/G 每个CD的时间不超过 20没有哪个CD的时间是超过N ...