多对多

多对多

模型类

  • 博客标签 : 多对多

  • 博客作者: 多对一

# 作者/用户: 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'))

视图类

添加博客以及对应的标签

  • 获取参数:

    • 博客标题

    • 博客作者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、名称

歌手 和 歌曲: 多对多

  1. 实现 模型类

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'))    

 

作业

  1. 模型类

    1. 用户: 用户名、密码

    2. 商品: 商品名、价格、销量

  2. 首页展示 商品列表

  3. 在商品后面显示 一个 收藏按钮,

  4. 点击收藏,判断用户是否 登录

    1. 用户登录,用户可以收藏成功(收藏前提是: 用户和 商品已经存在,收藏成功也就是 在 收藏表中存入 用户和商品的 关联关系

    2. 用户未登录,跳转到登录页面, 登录成功,返回 商品列表页

  5. 可以在用户中心页面,显示所有 已收藏的 商品列表

商品收藏模型类

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
}

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2021-06-07 15:47  憨憨的baby  阅读(214)  评论(0)    收藏  举报