首页 > 代码库 > Flask 学习 十一 关注着

Flask 学习 十一 关注着

数据库关系

1.1多对多关系

添加第三张表(关联表),多对多关系可以分解成原表和关联表之间的两个一对多的关系

多对多仍然使用db.relationship()方法定义,但是secondary参数必须设定为关联表,多对多关系可以在任何一个表中定义,backref参数会处理好关系的另一侧

1.2 自引用关系

如果关系中的两侧都在同一个表中称为自引用关系,在关注中,关系的左侧是用户实体,为关注着,关系的右侧也是用户实体,但是被关注着

本例的关联表是 follows,其中每一行都表示一个用户关注了另一个用户。图中左边表示的一对多关系把用户和 follows 表中的一组记录联系起来,用户是关注者。图中右边表示的一对多关系把用户和 follows 表中的一组记录联系起来,用户是被关注者。

技术分享

 1.3 高级多对多关系

在多对多关系中需要存储实体之间的额外信息,用户之间的关注可以把时间信息存储在关联表中

app/models.py/Follow 关注关联表模型的实现

class Follow(db.Model):
    __tablename__ = follows
    follower_id = db.Column(db.Integer,db.ForeignKey(users.id),primary_key=True)
    followed_id = db.Column(db.Integer, db.ForeignKey(users.id), primary_key=True)
    timestamp=db.Column(db.DateTime,default=datetime.utcnow)

app/models.py/User 使用两个一对多关系实现的多对多关系

class User(UserMixin,db.Model):
   。。。。   
# 为了消除外键间的歧义,定义关系时使用foreign_keys指定外键 # db.backref指的是回引Follow模型,lazy=‘joined‘可以实现立即一次性完成从连结查询中加载相关对象 # 如果把joined换成select就会成倍增加数据库查询次数 # lazy=‘dynamic‘ 直接返回查询对象,可以在执行查询之前添加过滤器 # cascade 参数配置在父对象上执行的操作对相关对象的影响 # 层叠选项可设定添加用户到数据库会话中,自动把所有的关系对象添加到会话中 # delete-orphan的作用是把默认层叠行为(把对象联结的所有相关对象的外键设为空值),变成删除记录后把指向该记录的实体也删除,这样就有效的销毁的联结 # ‘all,delete-orphan‘是逗号分隔的层叠选项,表示启用所有默认层叠选项并删除关联记录,all表示除了delete-orphan之外的所有层叠选项, followed=db.relationship(Follow,foreign_keys=[Follow.follower_id], backref=db.backref(follower,lazy=joined), lazy=dynamic, cascade=all,delete-orphan) followers = db.relationship(Follow, foreign_keys=[Follow.followed_id], backref=db.backref(followed, lazy=joined), lazy=dynamic, cascade=all,delete-orphan)

app/models.py/User 定义关注关系的辅助方法

class User(UserMixin,db.Model):
  。。。
def follow(self,user): if not self.is_following(user): # 把关注着和被关注着联结在一起传入构造器并添加到数据库中 f = Follow(follower=self,followed=user) db.session.add(f) def unfollow(self,user): # followed找到联结用户和被关注用户的实例 f = self.followed.filter_by(followed_id=user.id).first() if f : # 销毁用户之间的联结,删除这个对象即可 db.session.delete(f) def is_following(self,user): # 搜索两边指定的用户,如果找到返回True return self.followed.filter_by(followed_id=user.id).first() is not None def is_followed_by(self,user): # 搜索两边指定的用户,如果找到返回True return self.followers.filter_by(follower_id=user.id).first() is not None

 

Flask 学习 十一 关注着