• flask框架初学-07-数据库映射关系


    上节了解到如何在flask框架中对数据库进行简单一对一映射的增删改查操作,但数据库中表之间的关联不止一种。本节将以开发博客部分代码为例讲述如何在程序中处理数据库中表之间一对多和多对多关系,更完整代码将放在下一章。

    关系映射使用

    1对多、多对1

    在flask的框架中体现1对多的模型关系:通过外键ForignKey和relationship体现。ForignKey表现映射关系,relationship提供给模板使用

    比如一个作者在博客中存在多篇文章,一篇文章属于某个用户。我们需要通过文章找到写文章的作者,可以通过User类中的id找到唯一的作者信息,id是User类中的主键,需要在Article类中关联上User类中的id需要使用ForeignKey外键,即Article类中新增一个字段user_id,并赋值上db.ForeignKey(‘user.id’),相当于user_id就是user中的id.

    另外,我们还可以指定Article面向的类对象是User,backref指明了反向关系,即User对象模型可以通过articles访问Articles,反向关系只能在关联的两个类中的一个类中添加

    class User(db.Model):
        id = db.Column(db.Integer,primary_key = True,autoincrement = True)
        username = db.Column(db.String(15),unique=True,nullable=False)
        password = db.Column(db.String(64),nullable=False)
        phone = db.Column(db.String(11),nullable=False,unique= True)
        email = db.Column(db.String(30))
        icon = db.Column(db.String(100))
        isdelete = db.Column(db.Boolean,default=False)
        rdatetime = db.Column(db.DateTime,default = datetime.now())
        # articles = db.relationship('Article',backref='user')
    
    
    class Article(db.Model):
        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)
        love_num = db.Column(db.Integer,default=0)
        # 外键 同步到数据库的外键关系
        user_id = db.Column(db.Integer,db.ForeignKey('user.id'),nullable=False)
        # 可在user/models.py中添加 articles = db.relationship('Article',backref='user')
        user = db.relationship('User',backref='articles')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在视图中展示某篇Article的作者姓名

    <p>
        <div>作者:{{ article.user.username }}        
        发布时间:{{ article.pdatetime }}div>
    p>
    
    • 1
    • 2
    • 3
    • 4

    在视图中展示用户的所有文章

     <table class="table table-hover">
      <tr>
        <th>序号th>
        <th>文章标题th>
      tr>
      {% for article in user.articles %}
        
          <td>{{ loop.index }}td>
          <td>{{ article.title }}td>
        tr>
      {% endfor %}
    table>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    多对多

    场景:一个用户可买多个商品,一个商品可被多个用户购买

    class User(db.Model):
        id = db.Column(db.Integer,primary_key = True,autoincrement = True)
        username = db.Column(db.String(15),unique=True,nullable=False)
        password = db.Column(db.String(64),nullable=False)
        phone = db.Column(db.String(11),nullable=False,unique= True)
        email = db.Column(db.String(30))
        icon = db.Column(db.String(100))
        isdelete = db.Column(db.Boolean,default=False)
        rdatetime = db.Column(db.DateTime,default = datetime.now())
        # articles = db.relationship('Article',backref='user')
        
        
    class Goods(db.Model):
        id = db.Column(db.Integer,primary_key=True,autoincrement=True)
        gname = db.Column(db.String(100),nullable=False)
        price = db.Column(db.Float,nullable=False)
        # back reference 反向查找
        users = db.relationship('User',backref='goodslist',secondary='user_goods')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    方法一:建立中间关系表

    建立一个名为user_goods的表,存储user_id和good_id这两个字段,这两个字段分别是User的主键id和Goods的主键id

    user_id和good_id都设置为user_goods的主键,从而使两者组成复合主键,复合主键可组合查重

     tags = db.Table('user_goods',
                    db.Column('user_id',db.Integer,db.ForeignKey('User.id'),primary_key=True),
                    db.Column('good_id',db.Integer,db.ForeignKey('Goods.id'),primary_key=True)
                    )
    
    • 1
    • 2
    • 3
    • 4

    方法二:建立中间关系表

    关系表:user与goods之间的关系

    class User_goods(db.Model):
        id = db.Column(db.Integer,primary_key=True,autoincrement=True)
        user_id = db.Column(db.Integer,db.ForeignKey('user.id'))
        goods_id = db.Column(db.Integer,db.ForeignKey('goods.id'))
        number = db.Column(db.Integer,default=1)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    view.py

    # 用户找商品
    @goods_bp.route('/findgoods')
    def find_goods():
        user_id = request.args.get('user_id')
        user = User.query.get(user_id)
        return render_template('goods/findgoods.html',user=user)
    
    
    # 根据商品找用户
    @goods_bp.route('/finduser')
    def find_user():
        goods_id = request.args.get('gid')
        goods = Goods.query.get(goods_id)
        return render_template('goods/finduser.html',goods=goods)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

  • 相关阅读:
    查询sqlserver内存分配情况的SQL
    1065 A+B and C (64bit)
    多维时序 | MATLAB实现SSA-CNN-BiLSTM-Attention多变量时间序列预测(SE注意力机制)
    [WPF]浅析依赖属性(DependencyProperty)
    集合_Collection_LinkedList简述及增删机制源码简析
    Mysql学习笔记-临键锁实验
    linux三剑客awk、sed、grep与cut的总结
    国产FTP文件传输服务器需要具备哪些关键特性?
    索引签名的使用及松散索引签名
    算法~PBKDF2-SHA让密码更安全
  • 原文地址:https://blog.csdn.net/weixin_42724501/article/details/126225005