多对多
模型类
-
博客和标签: 多对多 -
博客和作者: 多对一
# 作者/用户: id、名称、性别、年龄
class Author(db.Model):
__tablename__ = 'tb_author'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(20), unique=True, nullable=False)
gender = db.Column(db.String(10), default='保密')
age = db.Column(db.Integer)
# 标签: id、名称
class Tag(db.Model):
__tablename__ = 'tb_tag'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(20), unique=True, nullable=False)
# 博客: id、标题、创建时间、作者id
class Blog(db.Model):
__tablename__ = 'tb_blog'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(100), nullable=False)
create_time = db.Column(db.DateTime, default=datetime.now)
author_id = db.Column(db.Integer, db.ForeignKey('tb_author.id'))
author = db.relationship('Author', backref='blogs')
# 因为 博客 和 标签之间没有直接关系, 想要 构建关系字段,需要指明 他们之间的 关系表
# 有这个字段之后,可以在 博客表 直接 查 标签 blog.tags
tags = db.relationship('Tag', secondary='tb_blog_tag', backref='blogs')
# 博客和标签之间的关系表
class BlogToTag(db.Model):
__tablename__ = 'tb_blog_tag'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
tag_id = db.Column(db.Integer, db.ForeignKey('tb_tag.id'))
blog_id = db.Column(db.Integer, db.ForeignKey('tb_blog.id'))
视图类
添加博客以及对应的标签
-
获取参数:
-
博客标题
-
-
标签列表
-
-
创建博客对象
-
根据标签字符串列表, 生成 一个 包含 所有标签对象的列表
-
将 博客对象 和 标签对象 之间 建立 关系
-
添加、提交事务
-
返回响应
# 添加博客时,顺便 添加 标签
class BlogView(Resource):
def post(self):
time = datetime.now().strftime('%Y-%m-%d')
parser = reqparse.RequestParser()
# 博客标题:不传,默认为当前 日期: 2021-6-3
parser.add_argument('title', type=str, default=time, location=['json', 'form'])
parser.add_argument('author_id', type=int, required=True, location=['json', 'form'])
# 当一个参数的键 对应 多个值,就需要使用 action属性 获取所有的值, 得到一个列表
parser.add_argument('tags', type=str, location=['json', 'form'], action='append')
args = parser.parse_args()
tags = args.get('tags') # 博客对应的 标签列表
author_id = args.get('author_id') # 博客的作者id
title = args.get('title') # 博客的标题
# 创建博客对象
blog = Blog(title=title, author_id=author_id)
# 创建所有的标签对象, 包含 标签名的 列表 变成 一个 包含 标签对象 的列表
tags = [Tag(name=i) for i in tags] # ['python', 'flask] ====> [ Tag(name='python'), Tag(name='flask) ]
# 添加第三张表的数据,也就是 博客 和 标签之间的 关系
blog.tags = tags
db.session.add(blog) # blog属于主体,提交博客,就会提交所有的数据
db.session.commit()
return {'msg': '添加成功'}, 201
查询博客详情以及对应标签
class BlogDetailView(Resource):
def get(self, pk):
blog = Blog.query.get_or_404(pk)
return {
'id': blog.id,
'title': blog.title,
'author': blog.author.name,
# 标签对象列表 ====> 标签字符串列表
'tags': [t.name for t in blog.tags]
}
练习
歌手:id、名字、性别
歌曲:id、名称
歌手 和 歌曲: 多对多
-
实现 模型类
class Singer(db.Model):
__tablename__ = 'tb_singer'
id = db.Colum(db.Integer, primary_key=True, authoincrement=True)
name = db.Cloum(db.String(20), unique=True, nullable=False)
gender = db.Colum(db.String(10))
songs = db.relationship('Song', secondary='tb_song_singer', backref='singers')
class Song(db.Model):
__tablename__ = 'tb_song'
id = db.Colum(db.Integer, primary_key=True, authoincrement=True)
name = db.Cloum(db.String(20), unique=True, nullable=False)
class SingerToSong(db.Model):
__tablename__ = 'tb_song_singer'
id = db.Colum(db.Integer, primary_key=True, authoincrement=True)
singer_id = db.Colum(db.Integer, db.ForeignKey('tb_singer.id'))
song_id = db.Colum(db.Integer, db.ForeignKey('tb_song.id'))
作业
-
模型类
-
用户: 用户名、密码
-
商品: 商品名、价格、销量
-
-
首页展示 商品列表
-
在商品后面显示 一个 收藏按钮,
-
点击收藏,判断用户是否 登录
-
用户登录,用户可以收藏成功(收藏前提是: 用户和 商品已经存在,收藏成功也就是 在 收藏表中存入 用户和商品的 关联关系)
-
用户未登录,跳转到登录页面, 登录成功,返回 商品列表页
-
-
可以在用户中心页面,显示所有 已收藏的 商品列表
商品收藏模型类
class Goods(db.Model):
__tablename__ = 'tb_goods'
id = xxx
name = xxx
class User(db.Model):
__tablename__ = 'tb_user'
id = xxx
username = xxx
password = xxx
goods = db.relationship('Goods', secondary='tb_fav', backref='users')
class Fav(db.Model):
__tablename__ = 'tb_fav'
id = xxx
user_id = db.Column(db.Integer, db.ForeignKey('tb_user.id'))
goods_id = db.Column(db.Integer, db.ForeignKey('tb_goods.id'))
大体的逻辑代码
收藏商品逻辑
# 1. 添加商品: 只是单纯 添加 商品记录,关系不用管
# 1. 添加用户: 只是单纯 添加 用户记录,关系不用管
# 3. 点击按钮,收藏商品, 在Fav表中需要添加 商品和 用户的 对应关系
# 1. 获取商品id和 用户id
...
user_id = args.get('user_id')
goods_id = args.get('goods_id')
# 2. 判断 商品id和用户id对应的信息是否存在
user = User.query.get_or_404(user_id)
goods = Goods.query.get_or_404(goods_id)
# 3. 添加关系
# 3.1 判断该商品是否被该用户收藏过
if Fav.query.filter_by(user_id=user_id, goods_id=goods_id).count() == 0:
# 3.1.1 商品未收藏,执行逻辑。收藏商品
fav = Fav(user_id=user_id, goods_id=goods_id)
db.session.add(fav)
db.session.commit()
return {
'msg':'商品收藏成功'
}, 201
else:
# 3.1.2 商品收藏过
return {
'msg': '商品已收藏'
}, 400
用户收藏的商品
# 1. 获取用户id
....
user_id = args.get('user_id')
# 2. 查询用户对象
user = User.query.get_or_404(user_id)
# 3. 通过用户对象,查询关联的收藏商品
data= [ {'id':g.id, 'name':g.name} for g in user.goods]
# 4. 返回数据
return {
'user': {
'id': user.id,
'username': user.username
},
'goods': data
}

浙公网安备 33010602011771号