一对多关系
- 一对多关系中, 外键设置在 多的一方
ForeignKey
- 外键使用类
sqlalchemy.schema.ForeignKey
来声明- 语法 :
db.Clolumn(db.Integer, db.ForeignKey('参照表.字段'), nullable=Flase)
- 语法 :
relationship
-
relationship()
作用主要在view和template中体现, 让两个有对应关系的模型能够互相查找- 比如在在一个类中取对应的外键的字段
-
关系使用
relationship()
函数表示- 语法 :
关联的模型名 = db.relationship('要关联的模型名', backref='反向查找时使用的名字')
backref
: 反向查找lazy
: 决定了SQLAlchemy什么时候从数据库中加载数据.- 默认是select : 就是什么时候查询什么时候加载
- 语法 :
# 用户 一个用户对应多篇文章 一
class User(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(15), nullable=False)
password = db.Column(db.String(100), nullable=False)
phone = db.Column(db.String(11), unique=True, nullable=False)
email = db.Column(db.String(30))
# 头像, 存放的是地址
icon = db.Column(db.String(100))
isdelete = db.Column(db.Boolean, nullable=False, default=0)
rdatetime = db.Column(db.DateTime, default=datetime.now)
# 创建关系属性 relationship("关联的类名", backref="对方表查询关联数据时的属性名")
article = db.relationship('Article', backref='user')
def __str__(self):
return self.username
# 文章模型 多
class Article(db.Model):
# id
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
# 标题
title = db.Column(db.String(50), nullable=False)
# 内容
content = db.Column(db.Text, nullable=False)
# 发布时间
pdatetime = db.Column(db.DateTime, default=datetime.now)
# 阅读数
click_num = db.Column(db.Integer, default=0)
# 收藏
save_num = db.Column(db.Integer, default=0)
# 点赞
like_num = db.Column(db.Integer, default=0)
# 用户外键 同步到数据库的外键关系
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
示例
- 添加文章
article/view.py
from flask import Blueprint, request, render_template
from apps.article.models import Article
from apps.user.models import User
from exts import db
article_bp = Blueprint('article', __name__)
@article_bp.route('/add_article', methods=['GET', 'POST'])
def publish_article():
if request.method == 'POST':
# 文章标题
title = request.form.get('title')
# 文章内容
content = request.form.get('content')
# 用户id
uid = request.form.get('uid')
# 添加数据
article = Article()
article.title = title
article.content = content
article.user_id = uid
db.session.add(article)
# 提交
db.session.commit()
return '添加成功'
else:
# 查询所有未删除的用户
users = User.query.filter(User.isdelete == False).all()
return render_template('article/add_article.html', users=users)
templates/article/add_article.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加文章</title>
</head>
<body>
<form action="{{ url_for('article.publish_article') }}" method="post" >
<p><input type="text" name="title" placeholder="文章标题"></p>
<p>
<textarea cols="50", rows="10" placeholder="输入文章内容" name="content">
</textarea>
</p>
<p>
用户 :
<select name="uid">
<option value="0">请选择用户</option>
{% for user in users %}
<option value="{{ user.id }}">{{ user.username }}</option>
{% endfor %}
</select>
</p>
<p><input type="submit" value="提交"></p>
</form>
</body>
</html>
relationship的作用 - 展示文章
article/all_article.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文章</title>
<style>
#container {
border: 1px solid brown;
margin-bottom: 10px;
padding: 5px;
}
</style>
</head>
<body>
{% for article in article_list %}
<div id="container">
<h1>标题 : {{ article.title }}</h1>
<h3>作者 : {{ article.user.username }}</h3>
<p>{{ article.content }}</p>
</div>
{% endfor %}
</body>
</html>
- 在user模型里面配置了反向查询的名字为
user
- 所以使用
article.user
会查找到一个user对象, 然后使用user对象.字段名
就可以获取到相应的字段
等同于sql语句
**select * from user, article on user.id=aticle.user_id
**