首页 > 技术文章 > flask多对多

doomqy 2021-06-07 09:30 原文

模型类

  • 博客标签 : 多对多

  • 博客作者: 多对一

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

 

 

 

 

 

 

推荐阅读